In MongoDB PHP, is it possible to update the value of a field using the value from another field?
The below Mongo Shell Command is working fine. Value of a field "product_name" is updating to the field "product_name_copy".
db.products.update(
{},
[{ $set: {
"product_name_copy": "$product_name"
}}],
{ multi: true }
)
But, While Am using this code in PHP,
PHP code :
$where = array();
$update = array('$set' => array("product_name_copy" => "$product_name"));
$options = array("multi" => true);
$bulkWrite = new MongoDB\Driver\BulkWrite;
$bulkWrite->update($where,$update,$options);
$updated = $mongo->executeBulkWrite("$db_name.products", $bulkWrite);
Am getting this error
Notice: Undefined variable: product_name in
C:\xampp\htdocs\mongo\mongo-update.php on line 10
If I used single quotes instead of double quotes,
$update = array('$set' => array("product_name_copy" => '$product_name'));
the same value $product_name is updating to the field "product_name_copy" like below.
{
"_id" : ObjectId("602a291f0406011059006c15"),
"product_id" : 15,
"product_name" : "Test Product",
"product_name_copy" : "$product_name"
}
Anyone know the solution for this problem.?
Finally I found the solution.
We need to put '$set' array into another one array for field value update.
PHP Code :
$where = array();
$update = array(array('$set' => array("product_name_copy" => '$product_name')));
$options = array("multi" => true);
$bulkWrite = new MongoDB\Driver\BulkWrite;
$bulkWrite->update($where,$update,$options);
$updated = $mongo->executeBulkWrite("$db_name.products", $bulkWrite);
Output of the above code is
{
"_id" : ObjectId("602a291f0406011059006c15"),
"product_id" : 15,
"product_name" : "Test Product",
"product_name_copy" : "Test Product"
}
This is what I exactly wanted.
Related
Ok, guys. As most of you might know, there is this new MongoDB Driver for PHP 7 out there. I was trying it out. I got stuck at this query here :
There is a collection like this:
{
"_id" : ObjectId("592d026e2a5e742704e60055"),
"name" : "One",
"conn" : [
{
"_id" : ObjectId("592d03cd3c83d5265c004d0b"),
"name" : "MongoDB Fans",
"comments" : "nice!"
},
{
"_id" : ObjectId("592d06513c83d5265c004d17"),
"name" : "SQL Fans",
"comments" : "not so nice!"
}
]
},
{
"_id" : ObjectId("592d0eec2a5e742704e60056"),
"name" : "Two",
"conn" : [
{
"_id" : ObjectId("592d0ef13c83d5265c004d37"),
"name" : "Cassandra Fans",
"comments" : "spooky!"
}
]
}
Now, what I want to achieve is this:
1. Find all "conn" fields (irrespective of which document they belong to) that contain a user input (say "xyz") in "name" as a sub-string.
2. Project the selected "conn" fields out.
I have tried using the following filters and options without success (Almost all of these return all the "conn" subsets instead of only the filtered subsets):
$filters = ["conn.name" => new MongoDB\BSON\Regex($name,'i')];
$options = ["projection" => ["_id" => 0,"conn" =>1];
$filters = ["conn" => ["\$all" =>["name" => new MongoDB\BSON\Regex($name,'i')]]];
$options = ["projection" => ["_id" => 0,"conn" =>1];
$filters = ["conn.name" => '/'.$name.'/i'];
$options = ["projection" => ["_id" => 0,"conn" =>1];
NOTE: I am using PHP 7 and the latest mongod PECL extension
I have the following json file with products details:
"products": [
{
"sku": 123,
"name": "iphone 7",
"categoryPath": [
{
"id": "abcat0800000",
"name": "Cell Phones"
},
{
"id": "pcmcat209400050001",
"name": "All Cell Phones with Plans"
}
],
}
]
I would like only to store the last value (ID and NAME) of the categoryPath Array:
"id": "pcmcat209400050001",
"name": "All Cell Phones with Plans"
My current code takes the json file, decode the json and insert in products table the information.
$json = File::get("/json/cell-0.json");
$data = json_decode($json);
$array1 = (array)$data;
//table products
foreach ($array1['products'] as $obj) {
DB::table('products')->insert(array(
'productSku' => ((isset($obj->sku) ? $obj->sku : 1)),
'productName' => ((isset($obj->name) ? $obj->name : null)),
'categoryId' => end($obj->categoryPath->id),
'categoryName' => end($obj->categoryPath->name)
));
Taking into consideration that array->categoryPath have multiple fields I would like to use a function (eg: end()) in order to take id and name only of the last values.
Using end($obj->categoryPath->id) I receive the following error ->
Attempt to modify property of non-object
Is this the best way to retrieve the last value of a multidimensional array?
You could use end() probably but your accessors would have to be outside the end() call (untested):
foreach ($array1['products'] as $obj) {
DB::table('products')->insert(array(
'productSku' => ((isset($obj->sku) ? $obj->sku : 1)),
'productName' => ((isset($obj->name) ? $obj->name : null)),
'categoryId' => end($obj->categoryPath)->id,
'categoryName' => end($obj->categoryPath)->name
));
The way you're getting the last element is incorrect, here is the refactored code. I also eliminated the need to cast data as an array as well.
$json = File::get("/json/cell-0.json");
$data = json_decode($json, true);
//table products
foreach ($data['products'] as $product) {
$lastCategory = isset($product['categoryPath']) && $size = sizeof($product['categoryPath']) ? $product['categoryPath'][$size-1] : array('id' => null, 'name' => null);
DB::table('products')->insert(
array(
'productSku' => isset($product['sku']) ? $product['sku'] : 1,
'productName' => isset($product['name']) ? $product['name'] : null,
'categoryId' => lastCategory['id'],
'categoryName' => lastCategory['name']
)
);
}
i'm trying to update an inner array within a mongo document:
$find = array('_id' => new mongoId($qId));
$push = array('$push' => array('questions', ['q' => $question, 'a' => $answers] ) );
$this->db->questionaires->update( $find, $push );
But I keep getting this error:
Invalid modifier specified: $push
My collection is structured like this:
> db.questionaires.findOne();
{
"_id" : ObjectId("57e7c1fea7312a9958601a85"),
"title" : "ff",
"respondantgroup" : "579dca85a7b294c3f030fb8d",
"responsible" : "579dc862a7b294c3f030fb8c",
"questions" : [
{
"q" : "",
"a" : [ ]
}
]
}
Any suggestions?
I was trying to query from mongodb using php, my database looks like this
{
"_id" : ObjectId("55892817d4302e281b8b4567"),
"subject" : "Report",
"createdAt" : ISODate("2015-06-23T09:34:15Z"),
"processedAt" : ISODate("2015-07-23T09:34:15Z"),
"testNumber" : 10
}
and my query is:
$procInMins = 60;
$anchor = new \DateTime('now', new \DateTimeZone('UTC')); // now
$anchor->sub(new \DateInterval('PT' . $procInMins . 'M'));
$query = array( "subject" => "Report", "processedAt" => array( '$gt' => $anchor));
$cursor = $collection->find($query);
and this returns a cursor whose count is 0, but i also tried
$query = array( "subject" => "ProcessOverflowSmsLogCommandTest Report", "testNumber" => array('$gt'=>3) );
in this case i compare the testNumber field and it returns 1 result, which is correct. So i think there's something wrong with the date, but I have no idea how to fix this. Thanks
I've thoroughly searched on the internet for this but haven't found a solution.
Problem : I want to update the quantity in this document. Criteria - itemId=126260, accessDays=30
`{
"_id" : ObjectId("547acfa95ca86bec2e000029"),
"session_id" : "1111",
"email" : "aasdasda#sdfsd.com",
"isProcessed" : 0,
"couponApplied" : "",
"countryId" : 2,
"items" : [
{
"itemId" : 126260,
"batchId" : 102970,
"accessDays" : null,
"quantity" : 2
},
{
"itemId" : 126260,
"batchId" : null,
"accessDays" : 30,
"quantity" : 2
}
]
}`
I am trying to do this using PHP :
`$condition = array( "session_id"=>'1111', 'items.itemId'=>126260, 'items.accessDays'=>30);
$new_values = array( '$set' => array("items.$.quantity" => 10) );
$cart_coll->update($condition, $new_values);`
But when I run this code, it updates the first nested object instead of the second.
What am I doing wrong here ? Does mongodb not consider multiple conditions in nested objects ?
You need to use $elemMatch to get the array marker to be in the right place. So your $query becomes
$condition = array( "session_id"=>'1111',
"items" => array(
'$elemMatch'=>array("itemId"=>126260, 'accessDays'=>30)));