Update MongoDB field using value of another field in PHP - php

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

PHP MongoDB Driver Query Only Specific Field From All Documents In Collection

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

Laravel php get last element in multidimensional array

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']
)
);
}

PHP mongo update failes. "Invalid modifier specified: $push"

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?

select by time from mongodb by using php error

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

PHP mongodb update on nested array with multiple conditions

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)));

Categories