Trying to do a simple mongodb query that drives me mad.... I have the following table/db:
[_id] => MongoId Object (
[$id] => 4f22efa1ef9dec8495b374bc
)
[h1] => a
[h2] => b
[h3] => c
[_id] => MongoId Object (
[$id] => 4f22efa1ef9dec8495b374bd
)
[h1] => d
[h2] => e
[h3] => f
Using the mongo tool command line and typing:
db.things.find({$or: [{'h1' : 'a'},{'h1': 'd'}]})
I get:
{ "_id" : ObjectId("4f22efa1ef9dec8495b374bc"), "h1" : "a", "h2" : "b", "h3" : "c" }
{ "_id" : ObjectId("4f22efa1ef9dec8495b374bd"), "h1" : "d", "h2" : "e", "h3" : "f" }
Which is fine. However trying doing the same from PHP, I get nothing ??:
$m = new Mongo();
$db = $m->selectDB('testdb');
$collection = new MongoCollection($db, 'things');
$query = array( '$or' => array( array('h1' => 'a')),
array('h1' => 'd'));
$cursor = $collection->find($query);
I do not see what I am doing wrong, but I have tried anything (or I think so) for 3 days now and it will not work. If I do queries using '>=' '<=' '<>' '<' '>' it works fine but using '=' as in this case it does not.
Thanks for your effort !
You're better off using $in for your given example, i.e.:
$collection->find(array('h1' => array('$in' => array('a', 'd'))));
As to why your query doesn't work - you're not using $or correctly (or infact, at all). This is the query you've put in the question reformatted:
$query = array(
'$or' => array(
array('h1' => 'a')
),
array('h1' => 'd')
);
Whereas you would need:
$query = array(
'$or' => array(
array('h1' => 'a'),
array('h1' => 'd')
)
);
If you have a look in the mongodb error log most likely it says something about that illegal loose top-level array in the conditions.
Related
After hours of experimentations and readings, I cannot find a solution to this problem:
I want to do a MongoDB->find($query) with multiple AND conditions.
For instance, say I want id = 5 and a < 6 and a > 2 and b > 10 and b < 20
I was expecting $query to be:
$query = array("id" => 5,
"a" => array('$gt' => 2,
'$lt' => 6),
"b" => array('$gt' => 10,
'$lt' => 20))
But this returns empty results with my DB
I tried various syntaxes such as:
$query = array("id" => 5,
array( "a" => array('$gt' => 2,
'$lt' => 6),
"b" => array('$gt' => 10,
'$lt' => 20)))
But this fails too.
Also tried with "$AND" variants, no luck.
Is it possible to "mix" several AND conditions in PHP-MongoDB find() requests?
I've just tested this using MongoDB PHP driver v1.6.11 (PHP-5.5.9). The test data are as below
db.collection.insert({id:5, a:4, b:15})
db.collection.insert({id:9, a:4, b:15})
db.collection.insert({id:5, a:4, b:20})
Using PHP code snippet:
$condition = array(
'$and' => array(
array(
"id" => 5,
"a" => array('$gt' => 2, '$lt' => 6),
"b" => array('$gt' => 10, '$lt' => 20)
)
)
);
$docs = $coll->find($condition);
foreach( $docs as $o=> $doc) {
echo json_encode($doc);
}
The above returns only the first document sample. This indicates that $and should work as expected. I've also tested without $and, i.e. :
$condition = array(
"id" => 5,
"a" => array('$gt' => 2, '$lt' => 6),
"b" => array('$gt' => 10, '$lt' => 20)
);
Which also works the same. Try checking your dataset, whether there is a document matching your criteria.
This issue is closed: bad value types in the DB (string instead of float/double). Works as expected when updating to correct types in DB.
Continuing on my project, I need to translate some SQL statements to mongoDB
My SQL Statement is:
Delete from 'table' where proc_id = $xxx and (day_id < $day OR day_id > $anotherDay)
Now my condition array is this:
$condicion = array(
'proc_id' => $xxx,
'$or' => array(
'day_id' => array(
'$lt' => $day,
'$gt' => $anotherDay
)
)
);
The function made for delete in mongo collections returns cannot delete...
Some help please?
Each "day_id" would be in it's own $or argument:
$query = array(
'proc_id' = > $xxx,
'$or' => array(
array( 'day_id' => array ( '$lt' => $day ) ),
array( 'day_id' => array ( '$gt' => $anotherDay ) ),
)
)
That is how $or conditions work as a "list" of possible expressions.
The JSON syntax is clearer to visualise:
{
"proc_id": $xxx,
"$or": [
{ "day_id": { "$lt": $day } },
{ "day_id": { "$gt": $anotherDay }}
]
}
Since there is a very clear distinction between a "list" and an "object" definition. $or conditions are "lists" of "objects", and that means you list the full condition just as if it were a query in itself. Since this is not called within an $elemMatch.
And of course the "DELETE" part is the .remove() method:
$collection->remove($query)
There are general examples and resources in the core documentation SQL to MongoDB Mapping Chart, where if the examples there do not immediately help, the linked articles and presentations should.
I have a deeply nested PHP array which I saved as a document in Mongo and ended up with this structure:
{
"_id" : "...",
"categ1" : {
"aaa" : 112.6736,
"bbb" : 83.9137,
"ccc" : 80.3322,
.....
},
"categ2" : {
"xxx" : 1,
"yyy" : 22,
"zzz" : 7,
"subcateg" : {
"sub1" : 1,
"sub2" : 22
}
}
}
Now, I have another array with a similar structure and I would like to increase the values of the record, by the values of the modifier array:
$modifier=array(
'categ1' => array(
'aaa' => 3,
'bbb' => -1,
'mmm' => 11
),
'categ2' => array(
'yyy' => -2,
'subcateg' => array(
'sub1' => -1
)
)
);
How can I increase the values inside the document by the values of the $modifier all at once, in a single query, and without loading the entire document ?
I've looked around the web but couldn't find any info on this.
Also, i'm pretty newbie at Mongo. Thanks
You can get your $modifier array to look like this:
$modifier = array(
'categ1.aaa' => 3,
'categ1.bbb' => -1,
'categ1.mmm' => 11,
'categ2.yyy' => -2,
'categ2.subcateg.sub1' => -1
)
Link for how to get that.
Then you should be able to simply use:
$col->update(
array("_id" => "..."),
array('$inc' => $modifier),
array("upsert" => true)
);
Originaly posted on cakephp Q&A but i'll put it up here in hope of getting some answers.
I have a bunch of companies that has a status of 0 as default but sometimes get a higher status. Now i want to use the high status if exists but revert to 0 if not. i have tried a bunch of different approaches but i always get either only the ones with status 0 or the ones with the status i want, never giving me status if exists and 0 if not.
Gives me only the status i specify, not giving me the ones with status 0:
'Company' => array (
'conditions' => array (
'OR' => array(
'Company.status' => 0,
'Company.status' => $status,
)
)
)
Gives me only status of 0:
'Company' => array (
'conditions' => array (
'OR' => array(
'Company.status' => $status,
'Company.status' => 0
)
)
)
Status definition and retrieving data in code:
function getCountry($id = null, $status = null) {
// Bunch of code for retrieving country with $id and all it's companies etc, all with status 0.
$status_less_companies = $this->Country->find...
if ($status) {
$status_companies = $this->Country->find('first', array(
'conditions' => array(
'Country.id' => $id
),
'contain' => array(
'Product' => array (
'Company' => array (
'conditions' => array (
'OR' => array(
'Company.status' => $status,
'Company.status' => 0
)
)
)
)
)
)
}
// Mergin $status_less_companies and $status_companies and returning data to flex application.
}
I changed the name for the models for this question just to make more sense, people are generaly frighten away when i tell them i work with cakephp for my flex application. I guess the logic to this question doesn't make sense but trust me that it makes sense in my application.
Thanks!
Try
'Company' => array (
'conditions' => array (
'OR' => array(
array('Company.status' => 0),
array('Company.status' => $status),
)
)
)
In the cookbook it says to wrap the or conditions in arrays if they are pertaining to the same field
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#complex-find-conditions
I'm not sure to have understood what results you expect. If you want to retrieve all records having status = 0, plus let's say the one having status = 3, you could use an 'IN' instead of an 'OR'.
In Cake, you would write it like this:
$status = 3;
$conditions = array('Company.status' => array(0, $status));
You can also fetch record by using following method:
put values in an array
e.g. $arr=array(1,2);
$res = $this->Model->find('all', array(
'conditions' =>array('Model.filedname'=>$arr),
'model.id' => 'desc'
));
I hope you will find answer.
$this->loadModel('Color');
$colors = $this->Color->find('all', [
'conditions' => [
'Color.is_blocked' => 0,
'Color.is_deleted' => 0,
'OR' => [
[
'Color.isAdmin' => $user_data['id'],
],
[
'Color.isAdmin' => 0,
]
],
]
]);
is it possible to find all records in an collection where the MongoID is not in
an provided array?
Something like this (?):
$search = array(
'_id' => array('$ne' => $ids)
'readby' => array('$ne' => $userId) // works
);
Iam using PHP with the Mongo Extension.
Use $nin instead of $ne with arrays. Something like:
$search = array(
'_id' => array('$nin' => $ids),
'readby' => array('$ne' => $userId)
);
should do what you want.