I try NoSQL.
I know how delete by id
$criteria = array(
'_id' => new MongoId('5277aeb6b28fada80a00002b'),
);
$users->remove($criteria);
but how to delete if you new for example value, like "name"="John"
You have to do absolutely the same thing as you have done with _id field:
$users->remove(array(
'name' => 'John'
));
You can always look at mongodb php documentation to find how to transform mongodb shell code to php.
I don't now how it is represented in PHP, but in Scala you would do something like this:
val criteria = MongoDBObject("name" -> "John")
coll.remove(criteria)
Related
In my MongoDB collection, all documents contain a mileage field which currently is a string. Using PHP, I'd like to add a second field which contains the same content, but as an integer value. Questions like How to change the type of a field? contain custom MongoDB code which I don't want to run using PHP, and questions like mongodb php Strings to float values retrieve all documents and loop over them.
Is there any way to use \MongoDB\Operation\UpdateMany for this, as this would put all the work to the database level? I've already tried this for static values (like: add the same string to all documents), but struggle with getting the data to be inserted from the collection itself.
Some further hints:
I'm looking for a pure PHP solution that does not rely on any binary to be called using exec. This should avoid installing more packages than needed on the PHP server
Currently, I have to use MongoDB in v4.0. Yes, that's not the most recent version, but I'm not in the position to perform an upgrade
Try this, please:
01) MongoDB Aggregate reference:
db.collectionName.aggregate(
[
{ "$addFields": {
"intField": { "$toInt": "$stringFieldName" }
}},
{ "$out": "collectionName" }
]
)
02) Possible PHP solution (Using as reference https://www.php.net/manual/en/mongocollection.aggregate.php):
$pipeline = array(
array(
'$addFields' => array(
'integerField' => array('$toInt' => '$mileage')
)
),
array(
'$out' => 'collection'
),
);
$updateResult = $collection->aggregate(pipeline);
You could use $set like this in 4.2 which supports aggregation pipeline in update.
$set stage creates a mileageasint based on the previous with $toInt value
db.collection.updateMany(
<query>,
[{ $set: { "mileageasint":{"$toInt":"$mileage" }}}],
...
)
Php Solution ( Using example from here)
$updateResult = $collection->updateMany(
[],
[['$set' => [ 'mileageasint' => [ '$toInt' => '$mileage']]]]
);
I have a collection in my Mongo Database called WorkOrder with 2 fields DateComplete and DateDue. Using those 2 fields I'd like to use the aggregation framework to count the number of 'Late' Work Orders by comparing the two fields. However the research I've found hasn't had any useful ways to format the query so that the 'Late' Work Orders will be filtered through. Does anyone know of a way to format a Mongo DB Aggregation Query (preferably in PHP) that can compare 2 fields in the collection?
EDIT:
An example entry in WorkOrder might look like
_id
some mongo id
DateDue
2014-10-10
DateCompleted
2014-10-12
This entry would want to be filtered through since DateCompleted is greater than DateDue. I didn't know about the $cond operator so I haven't tried anything for that yet.
EDIT:
After trying #BatScream's suggestion with the following query in my PHP script
array(
'$cond' => array(
'if' => array(
'dateDue' => array(
'$lt' => 'dateComplete
)
)
)
)
However the MongoCollection::Aggregate function told me that $cond wasn't a recognized operator.
EDIT: #BatScream's answer seems to work but I wasn't aware of the fact that the group operator doesn't work properly after a $project is applied. I was hoping to be able to group these document on another field cID, is that possible?
The below aggregation pipeline would give you the result, considering your fields are of ISODate type. If not i suggest you to store them as ISODate type and not Strings.
db.collection.aggregate([
{$project:{"isLateWorkOrder":{$cond:[{$lt:["$dateDue","$dateCompleted"]},
true,false]}}},
{$match:{"isLateWorkOrder":true}},
{$group:{"_id":null,"lateWorkOrders":{$sum:1}}},
{$project:{"_id":0,"lateWorkOrders":1}}
])
The PHP syntax should look similar to,
$projA = array("isLateWorkOrder" =>
array("$cond" =>
array(array("$lt" =>
array("$dateDue","$dateCompleted")),
true,false)))
$matchA = array("isLateWorkOrder" => true)
$grp = array("_id" => null,"lateWorkOrders" => array("$sum" => 1))
$projB = array("_id" => 0,"lateWorkOrders" => 1)
$pipeline = array($projA,$matchA,$grp,$projB);
$someCol -> aggregate($pipeline)
or, simply using the count function:
db.collection.count({$where:"this.dateDue < this.dateCompleted"})
Usually when I search for one related ID I do it like this:
$thisSearch = $collection->find(array(
'relatedMongoID' => new MongoId($mongoIDfromSomewhereElse)
));
How would I do it if I wanted to do something like this:
$mongoIdArray = array($mongoIDfromSomewhereElseOne, $mongoIDfromSomewhereElseTwo, $mongoIDfromSomewhereElseThree);
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => new MongoId(mongoIdArray)
)));
I've tried it with and without the new MongoId(), i've even tried this with no luck.
foreach($mongoIdArray as $seprateIds){
$newMongoString .= new MongoId($seprateIds).', ';
}
$mongoIdArray = explode(',', $newMongoString).'0';
how do I search '$in' "_id" when you need to have the new MongoID() ran on each _id?
Hmm your rtying to do it the SQL way:
foreach($mongoIdArray as $seprateIds){
$newMongoString .= new MongoId($seprateIds).', ';
}
$mongoIdArray = explode(',', $newMongoString).'0';
Instead try:
$_ids = array();
foreach($mongoIdArray as $seprateIds){
$_ids[] = $serprateIds instanceof MongoId ? $seprateIds : new MongoId($seprateIds);
}
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => $_ids)
));
That should produce a list of ObjectIds that can be used to search that field - relatedMongoID.
This is what I am doing
Basically, as shown in the documentation ( https://docs.mongodb.org/v3.0/reference/operator/query/in/ ) the $in operator for MongoDB in fact takes an array so you need to replicate this structure in PHP since the PHP driver is a 1-1 with the documentation on most fronts (except in some areas where you need to use an additional object, for example: MongoRegex)
Now, all _ids in MongoDB are in fact ObjectIds (unless you changed your structure) so what you need to do to complete this query is make an array of ObjectIds. The ObjectId in PHP is MongoId ( http://php.net/manual/en/class.mongoid.php )
So you need to make an array of MongoIds.
First, I walk through the array (could be done with array_walk) changing the values of each array element to a MongoId with the old value encapsulated in that object:
foreach($mongoIdArray as $seprateIds){
$_ids[] = $serprateIds instanceof MongoId ? $seprateIds : new MongoId($seprateIds);
}
I use a ternary operator here to see if the value is already a MongoId encapsulated value, and if not encapsulate it.
Then I add this new array to the query object to form the $in query array as shown in the main MongoDB documentation:
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => $_ids)
));
So now when the query is sent to the server it forms a structure similar to:
{relatedMongoId: {$in: [ObjectId(''), ObjectId('')]}}
Which will return results.
Well... I came across the same issue and the solution might not be relevant anymore since the API might have changed. I solved this one with:
$ids = [
new \MongoDB\BSON\ObjectId('5ae0cc7bf3dd2b8bad1f71e2'),
new \MongoDB\BSON\ObjectId('5ae0cc7cf3dd2b8bae5aaf33'),
];
$collection->find([
'_id' => ['$in' => $_ids],
]);
I am building a simple messaging system, and i have a collection in mongodb with documents like this:
{ "_id" : ObjectId("50ad003f9811e5bc5c000000"), "between" : [ "user1,user2,user3" ] }
I want to perform this query:
db.conversations.find({'between': ["user1,user2,user3"]});
to get this exact document back. This query works in mongo shell.
in php-mongo, i tried this:
$collection->find(array("between"=>array("user1", "user2", "user3")));
but it does not work.
What am i doing wrong ?
Wouldn't you want to do an In query here?
db.collection.find( { "between" : { $in : ["user1", "user2", "user3"] } } );
See In query here:
Mongo Advanced $in query
making your PHP query look like:
$collection->find(array("between"=>array("$in"=>array("user1", "user2", "user3"))));
//untested, should be something similar to this.
or if you're trying to find it exactly wouldn't you just be able to do:
$collection->find(array("between"=>array("user1,user2,user3")));
First of all when you are saving your data you have to use array not a string
{ "between" : [ "user1,user2,user3" ] }
this stores in "between" an array of one element "user1,user2,user3"
Basically when you do your query in shell everything is ok, because you are asking for a array with one element. But in php you are asking for an array of three elements.
So, when you save your data, most probably that is what you need :
{ "between" : [ "user1","user2","user3" ] }
and this will give you an array of three users.
Then read the documentation http://www.mongodb.org/display/DOCS/Advanced+Queries to and adjust your query depends on what you need: either the exact array or only some elements in the array
Have you tried:
$collection->find(array("between"=>"user1,user2,user3"));
or
$collection->find(array( "$elemMatch" => array( "between"=>"user1,user2,user3" ));
The $in operator is analogous to the SQL IN modifier, allowing you to specify an array of possible matches.
Consider the following example which uses the $or operator.
$collection->find([
'select' => ['$in' => ['option 1', 'option 2', 'option 3']]
]);
References
I want to get the max id value on a collection.
How do I convert the mongoDb query:
db.tweets.find({},{id:1}).sort({id:-1}).limit(1)
to Mongo Query Language Statement using PHP?
I'm trying
$db->tweets->find(
array(),
array("id"=>1)
)->sort(array("id"=> -1))->limit(1);
but that doesn't work.
I checked this and it works for me:
$val = $db->myCollection->find(array(), array('_id' => 1))->sort(array('_id' => -1))->limit(1);
The error in your code is that it should be "_id" and not "id". Also, I hope $db->tweets is a MongoCollection object and you have ensured this. Hope this helps.