Find query with and operator in PHP - mongodb

Hi i am working on backend of web application & want to find the documents from mongodb database that contain key active_status with value set to both 1 & 2. With mongodb PHP i am confused of how to find with both parameters in single query.
My query was this:
$mongoDb = MongoDbConnector::getCollection("endusers");
$endUserData = $mongoDb->find(array('active_status' => 1, '$and' => array('active_status' => 2)));
I have to fetch the users whose active_status should be 1 & 2. The above query doesnt seems to work. What is the right one for that?
Thanks on advance for quick response.

You have $and the wrong way around. Both arguments need to be included:
$endUserData = $mongoDb->find(array(
'$and' => array(
array( 'active_status' => 1 )
array( 'active_status' => 2 )
)
));
And since that would only make sense when looking for both elements within an array element, then you should instead use $all, which is shorter syntax:
$endUserData = $mongoDb->find(array(
'active_status' => array( '$all' => array(1,2) )
));
I should add that unless you intend to match a document like this:
{ "active_status" => [1,2] }
The you do not in fact want $and at all, but rather you want $or or better yet $in for multiple possible values on the same field:
$endUserData = $mongoDb->find(array(
'active_status' => array( '$in' => array(1,2) )
));
This matches documents like this:
{ "active_status": 1 },
{ "active_status": 2 }

Related

Find query MongoDB using CakePHP

The following is the json array I have in a collection called claims in MongoDB.
{
"xmllisting_id": "537f371fb2e380922fff0e2c",
"pharmacyfiles_id": "537f3402b2e380732aa6032d",
"claim": {
"MemberID": "097110330047532601",
"PatientShare": "0",
},
"modified": ISODate("2014-05-23T13:12:17.191Z"),
"created": ISODate("2014-05-23T13:12:17.192Z")
}
I need to find all claims with a specified MemberID.I have tried the following in CakePHP without any success.
$claims = $claimobj->find(
'all',
array(
'conditions' => array(
'claim' => array('MemberID' => '097110330047532601')
)
)
);
How can I do it?
Finding "nested" details in MongoDB usually requires "dot notation". Otherwise you are actually asking for an object that has "exactly" the key and "only" the key you are specifying to match. Which of course it does not, as there is more information there:
$claims = $claimobj->find(
'all',
array(
'conditions' => array(
'claim.MemberID' => '097110330047532601'
)
)
);
So the path is "claim.MemberID" and not 'claim' => array('MemberID' => '097110330047532601' ) as you have written.

Mongodb-PHP: find query with '$and' function is not working

i am working on mongodb & php & want to retrive data based on multiple conditions.
I want to retrive forms whose form_status is both Active & Draft only
My query is:
$formData = $formInfo->find(array('team_id' => $_GET['id'], '$and' =>array('form_status' => 'Active','form_status' => 'Draft')));
It is not working. What could be the right syntax in PHP??
The $and operator takes a "real array" of documents as it's argument. In PHP you wrap the array to produce that kind of syntax:
$formData = $formInfo->find(
array(
'team_id' => $_GET['id'],
'$and' => array(
array( 'form_status' => 'Active' ),
array( 'form_status' => 'Draft' )
)
)
);
Note that this really woudn't make any sense unless "form_status" is actually and array itself. In which case the $all operator is a much cleaner approach:
$formData = $formInfo->find(
array(
'team_id' => $_GET['id'],
'form_status' => array(
'$all' => array( 'Active', 'Draft' )
)
)
);
And again if this field was not an array then you really meant $or but that can also be more clearly written for the same field with $in:
$formData = $formInfo->find(
array(
'team_id' => $_GET['id'],
'form_status' => array(
'$in' => array( 'Active', 'Draft' )
)
)
);
So $all is to $and what $in is to $or, but just allows you to use the same field without specifying the full document form

How to keep orders in MongoDB?

In my MongoDB document I have object like this
[_id] => MongoId Object (
[$id] => 52a46b44aabacb5c218b4567
)
[results] => Array (
[http://google.com] => Array (
[position] => 1
[data] => 42672
)
[http://bing.com] => Array (
[position] => 2
[data] => 9423
)
[http://yandex.com] => Array (
[position] => 3
[data] => 5513
)
)
I would like to change data parameter in "bing.com" from 9423 to for instance 300. Moreover, I have to keep order of the sites. It have to looks like this
[_id] => MongoId Object (
[$id] => 52a46b44aabacb5c218b4567
)
[results] => Array (
[http://google.com] => Array (
[position] => 1
[data] => 42672
)
[http://bing.com] => Array (
[position] => 2
[data] => 300
)
[http://yandex.com] => Array (
[position] => 3
[data] => 5513
)
)
Is this achievable in Mongo?
The reordering of fields issue has been fixed as of MongoDB v2.5.2 (2.6 release). Having said that one way you can avoid the issue completely is having results as an array instead of a (sub)document. Also note you should not use "." as part of the key name either.
With 2.4, with the following you will see there is reodering in the case of _id=1 (subdocument) but not in the case of _id=2 (array).
$document = array("_id" => 1, "results" => array('http://google.com' => array('position' => 1, 'data' => 42672),
'http://bing.com' => array('position' => 2, 'data' => 9423),
'http://yandex.com' => array('position' => 3, 'data' => 5513)));
$coll->insert($document);
$document = array("_id" => 2, "results" => array(array('site' => 'http://google.com', 'data' => 42672),
array('site' => 'http://bing.com', 'data' => 9423),
array('site' => 'http://yandex.com', 'data' => 5513)));
$coll->insert($document);
$coll->update(array("_id" => 1), array('$set'=>array("results.http://bing.com.data"=>300)));
$coll->update(array("_id" => 2, 'results.site' => 'http://bing.com'), array('$set'=>array('results.$.data'=>300)));
I've included examples below using the mongo shell for clarity, but the PHP equivalent should be straightforward to work out.
I notice you originally modelled your list of sites as an embedded document, however the order of fields within an embedded document is currently not guaranteed to be preserved so you should instead use an array.
Additionally, you cannot use field names with embedded dots (.) in MongoDB so you should not plan to store urls as field names (see: Field name restrictions).
In order to find an element in an array you need to search by a value (not a field name) so your schema should look more like:
{
_id: ObjectId("52a46b44aabacb5c218b4567"),
results: [
{
site: 'http://google.com',
position: 1,
data: 42762
},
{
site: 'http://bing.com',
position: 2,
data: 9423
},
{
site: 'http://yandex.com',
position: 3,
data: 5513
}
]
}
Assuming the array site elements are unique, you can use the positional operator $ to find and update the matching embedded document in place.
For example, to perform your update of the "bing.com" data value:
db.sites.update(
// Match criteria
{
_id:ObjectId("52a46b44aabacb5c218b4567"),
'results.site':'http://bing.com'
},
// Update
{ $set: {
'results.$.data': 300 }
}
)
In MongoDB 2.4+ you have the option of pushing to a sorted array which could also be a useful approach to maintaining your array in sorted order when you add new entries.
It's worth noting that if you plan to store many (i.e. thousands) of items in an array this can impose a significant performance penalty due to document growth and the complexity of updating large arrays.
I am pretty sure that (as every other DBMS) you can't and should't rely on records orders.
Instead I would advice you to add index (on position, i.e. db.people.ensureIndex( { position: 1 } )) and query your record sorted by that field, i. e.: db.collection.find().sort( { position: 1 } )

With cakephp2.3 and mongoDB how to add array in a document?

how can I work with lists within the mongoDB?
For example, I have a document (class), and a list of students in this class, ie a subdocument (students).
What do not you, is to add more students to a class.
in Model:
public function salvar($name,$idClass){
$new = array(
"_id" => $idClass,
"student"=> array(
'idStudent' => new MongoId(),
'name' => $name));
return $this->save($new);
}
But when you add a new student, he is not working that way.
How to perform a $push update
The answer you've provided clarifies what you've been trying to do. However, the solution is a little convoluted. To perform a $push update with MongoDB, simply specify you want to perform a push update:
$this->Foo->save(array(
'_id' => $id,
'$push' => array(
"images" => array(
'id' => new MongoId(),
'name' => $name,
'size' => $size
)
)
);
You can use the mongoNoSetOperator property to achieve the same thing but
It's indirect, therefore not obvious
With multiple calls to save in the same request it can be confusing if it's not reset to $set if it's modified
It prevents using multiple operators in a single call.
There's more information about using different update operators in the documentation.
the answer to the question was:
public function salvar($name,$size,$id){
$this->mongoNoSetOperator = '$push';
// fixed array data structure
$susp = array(
"_id" => $id,
"images"=> array(
array(
'id' => new MongoId(),
'name' => $name,
'size' => $size
)
)
);
return $this->save($susp);
}
Note: Thank Garamon from github, by clear and objective answers.

MongoDB (via Fuelphp): Adding entries on an Array

I would appreciate the help here. For the purpose of this discussion I have an example here (I will use paste bin for the codes):
http://pastebin.com/VPuyKn6W
I am trying to produce this output:
http://pastebin.com/4iMLacRu
I understand that I need to use $push to make this work. But upon testing, it doesn't seem to do anything. I am following the instructions as prescribed in the docs, but instead of using $Id, I am using user_id for finding the document in the collection. Here is my model:
http://pastebin.com/QB94tbZn
Am I misunderstanding something, or I am not using the $push operator properly, or something to do on how I created the document?
After walking outside, I finally got my answer.
public static function create_mongo()
{
$data = array(
'user_id' => '123895',
'First_Name' => 'John',
'Last_name' => 'Doe',
'sites' => array(
array(
'title' => 'Sankaku Complex',
'site' => 'http://sankakucomples.com'
)
)
);
$db = Fuel\Core\Mongo_Db::instance();
$db->insert('test_collection',$data);
}
sites should be an array carrying an array variable.