I'm having problem to achieve this.
I have this piece of code which I had tested in Rock Mongo and it works fine.
array(
'TEST' =>
array( '$in' =>
array( new MongoRegex('/^(?!TESTVALUE)/$ig'))
)
)
Above piece of code return me all documents which haven't value "TESTVALUE" for the key "TEST".
Now what I want to achieve?
First I don't know how to write piece of code to fetch all documents which haven't values "TESTVALUE" & "SECONDVALUE" for the key "TEST".
That will be something like this:
array(
'TEST' =>
array( '$in' =>
array( new MongoRegex('/^(?!TESTVALUE)/$ig'),new MongoRegex('/^(?!SECONDVALUE)/$ig') )
)
)
And also I will need above piece of code written in PHP.
Any kind of help or suggestions is welcome and will be appreciated.
Thanks in advance
I don't think you can use $in like that, but this should work:
'TEST' => array('$and' => array(
array('$regex' => new MongoRegex('/^(?!TESTVALUE)/$ig'),
array('$regex' => new MongoRegex('/^(?!TESTVALUE)/$ig')))
something to that effect (untested)
Your queries and your description seem to contradict each other. If you want a query for all documents which don't have some string as the field value, why are you using regexes? Do you not want the value to be a substring of the field value? If you just want to do a query like "find documents where the value of the TEST field is not "X" or "Y", use $nin ("not in"):
db.collection.find({ "TEST" : { "$nin" : ["X", "Y"] } })
If the field should match multiple regexes, then either combine them into a single regex or combine the conditions with $and.
Related
I'm trying to write a simple Mongo query to return all documents where the value of a field is null (or an empty array, I'm not sure what you call it).
Here is my query;
db.getCollection('contact').find({'poco.name.email':false})
Here is a screenshot of my collection using RoboMongo;
Ultimately, I need to transfer this to some PHP. So far I have this working;
$conditions = array_merge($conditions, [
'owner.$id' => $this->getId(),
'poco.name.familyName' => "Smith",
//not sure what goes here.. something like
//'poco.emails' => null,
]);
return Model_Mongo_Contact::getContacts($conditions, $sort, $fields, $limit, $skip);
That's probably going to be harder to answer without more access to the methods.. Or maybe not I am very new to Mongo it might be really obvious.
I'm not PHP expert but I'll be doing in mongo shell as:
db.collection.find({
$and: [
{"poco.email":{$exists: true}},
{"poco.email":{$ne: []}}
]})
Query above will list all documents where poco.name.email is not missing and is not empty.
The basic concept when looking for an "empty" array or even "non-existent" is to use a property of "dot notation" and search where the 0 index of the array does not exist. This can be achieved with using the $exists operator:
$conditions = array_merge($conditions, [
'owner.$id' => $this->getId(),
'poco.name.familyName' => "Smith",
'poco.emails.0' => array( '$exists' => FALSE )
]);
That condition is true when either there is no property at all, or if it is something other than an array ( therefore no "0" field property ) or indeed an "empty" array ( since there is no content at the first index ).
This works best when the field is actually "indexed". So if in your "normal" structure you have "sub-documents" inside the array element with say a consistent field named "address" which is indexed as "poco.emails.address", then you are best of pointing to that specific indexed property to see if it $exists or not:
$conditions = array_merge($conditions, [
'owner.$id' => $this->getId(),
'poco.name.familyName' => "Smith",
'poco.emails.0.address' => array( '$exists' => FALSE )
]);
But if the array consists purely of "values" only and no "sub-documents", then simply testing for the 0 index position of the array as initially demonstrated will be enough.
I've come across an odd problem using CakePHP 1.3 to find information. Let's use this dbschema as an example:
id is int(11) PRIMARY auto_increment
amount is float(10,2) NULL
status is ENUM(Completed, Removed, Pending)
id amount status
1 100.00 Completed
2 100.00 Removed
3 100.00 Completed
4 100.00 Completed
5 100.00 Pending
When using Cake's find to retrieve data from this table, I use this query:
$this->Testtable->find('all', array(
'conditions' => array(
'status LIKE ' => 'Removed',
'status LIKE ' => 'Pending',
'status LIKE ' => 'Completed'
)
))
Looking at this query, I would assume that Cake would return all rows that match all of those conditions (which is totally acceptable in SQL), however it only uses the last condition and returns WHERE status LIKE 'Completed'.
I ran a test doing this, which returned all rows correctly (I know it's a more "correct" way to do the query anyway):
'conditions' => array(
'status' => array('Removed', 'Pending', 'Completed')
)
Take the opposite for an example, I want to return all rows that aren't Removed or Pending:
'conditions' => array(
'status !=' => 'Removed',
'status !=' => 'Pending'
)
This query returns all rows with Completed and Removed, as it only listens to the last statement. I assume that this is happening because instead of concatenating these search conditions into the query, Cake is overwriting the conditions based on the "field" being status !=. I can prove this theory by adding a space after the != in either of those conditions, creating the desired result of only Confirmed records.
Can anybody tell me why Cake would do this? As this is a legitimate thing to do in SQL, I see no reason that Cake wouldn't allow you to do it. Does anybody know if this issue is fixed up in newer versions of Cake?
I suppose that this comes down to the fact that at the end of the day, I am reassigning the array value based on that key, and it's not actually CakePHP's fault at all. I had a look into Cake's model.php and found this:
$query = array_merge(compact('conditions', 'fields', 'order', 'recursive'), array('limit' => 1));
I ran a test:
$array = array(
'conditions' => array(
'test' => 'yes',
'test' => 'no'
)
);
$var = 'hello';
$c = compact('array', 'var');
print_r($c);
As mentioned above, compact is only receiving the value no from the test key. I assumed that the use of compact to merge variables/arrays into the query would recursively merge similar keys from the conditions array into the last specified, but it turns out that yes isn't even making it that far as it's being redefined on the spot.
I suppose this is a limitation of PHP rather than Cake, but it is still something that didn't occur to me and should be done differently somehow (if it hasn't already) in future.
Edit
I ran a couple more tests. I wrapped identical conditions in their own arrays, then compared them the way Cake's find functions would. Using compact (which Cake does) the arrays containing identical keys remain intact, however using array_merge, the first key is overwritten by the second. I guess in this case it's a very, very good thing that Cake uses compact instead of array_merge to merge its query criteria.
$array = array(
array('test' => 'yes'),
array('test' => 'no')
);
$m = array_merge($array[0], $array[1]);
$c = compact('array');
print_r($c);
print_r($m);
Result:
Array
(
[array] => Array
(
[0] => Array
(
[test] => yes
)
[1] => Array
(
[test] => no
)
)
)
Array
(
[test] => no
)
While this is obviously a simple problem in the way you fundamentally write PHP code, it wasn't inherently obvious while writing in Cake syntax that conditions would overwrite each other...
Basic PHP: Don't use the same array key twice
'conditions' => array(
'status LIKE ' => 'Removed',
'status LIKE ' => 'Pending',
'status LIKE ' => 'Completed'
)
should be
'conditions' => array(
'status LIKE' => array('Removed', 'Pending', 'Completed'),
)
Same for any other array key.
Note that some quick debugging of the array reveals this.
Please also see the tons of other stackoverflow questions with the same issue or other areas where basic research could have pointed you in this direction. Taking a look there first can help to resolve the issue in less time.
This may be a very easy thing to do, but I'm pretty new to MongoDB and am having trouble making this word right.
I'm pulling leads from a database, and I only want it to pull records where the email field is not empty. I've tried putting in the statement to skip the record if it's not null, but there are many fields that aren't null, but don't have any characters in them, either. Here is my MongoDB query:
$records = $dbh->find('email' => array('$ne' => null))->limit(2000);
I also tried 'email' => array('$ne' => '')) but that didn't do the trick either.
Is there a simple way to do this? I know in MySQL it would be a simple where email != "" but I'm still learning my way around Mongo :) Thanks!
Try this, you are enclosing into array improperly
$records = $dbh->find(array("email" => array('$ne' => null)))->limit(2000);
Ok, I just figured out a decent way, and will post it for any other "noob" like me who's having the same problem :)
I used '$nin' with an array and it fixed the problem. Here's my query now:
$records = $dbh->find(array("email" => array('$nin' => array(' ','',null))))->limit(2000);
After 3 hours of failing, I managed to do it in a tricky way:
find('field' => array('$regex' => '.*'))
$records = $dbh->find('$or'=>array(
array('email'=>array('$exists' => false)),
array('email'=>array('$ne' => null)),
array('email'=>array('$ne' => ''))
));
You could also do this like
$records = $dbh->find(array('$where' => 'this.email && this.email.length'))->limit(2000);
I can't figure out for the life of my to select from a collection with the or parameter. It's not working at all for me and I can't really find any documentation on it for php.
Here is my example code that doesn't return anything even though they exist in the collection:
$cursor = $products->find(
array(
'$or' => array(
"brand" => "anti-clothes",
"allSizes" => "small"
)
)
);
The $or operator lets you use boolean or in a query.
You give $or an array of expressions, any of which can satisfy the query.
You provided only one element in the array. Use:
find(array('$or' => array(
array("brand" => "anti-clothes"),
array("allSizes" => "small")
)));
First i am a beginner in programming in general, i am trying to create a program for using gps locations from Lightroom on a map in googlemaps.
When i use the print the strings below ti the screen i see 5 different value's, this is also what i want, but...
I want to create also 5 different markers on the map this is done by the addMarkerByCoords Function but how can i use the 5 value per strings in the function ?
I have tried array, foreach but i cannot getting to work. The not working part can and probably will be my fault. LOL
print_r ("$Loncoord");
print_r ("$Latcoord");
print_r ("$gui");
//$map->formatOutput = true;
$map->addMarkerByCoords("$Loncoord","$Latcoord","$gui",'<b>Old Chicago</b>');
Can somebody give me a hint ?
To: Jonathan Sampson:
outputs print_r :-5.68166666667, +24.6513888889,IMG_3308,index.html,Landschap
To: Anti Veeranna I removed the " marks (and the program still works), but can you explain why this is better ?
And to the others Thank you very very much for the effort,work and really quick responses.
Assuming that this is PHP, you could us an array of arrays, and then loop.
Something like this:
$items = array(
array(
'long' => 12.34567,
'lat' => 34.56789,
'gui' => '????',
'location' => 'old chicago'
),
...
array(
'long' => 12.34567,
'lat' => 34.56789,
'gui' => '????',
'location' => 'old chicago 5'
)
);
foreach ($items as &$item) {
$map->addMarkerByCoords(
$item['long'],
$item['lat'],
$item['gui'],
$item['location']
);
}
unset($item);
$map->addMarkerByCoords(Array($Loncoord, $Latcoord, $gui, '<b>Old Chicago</b>));
??