Multi update with $set and php Mongo - php

I'm trying to update multiple items in a collection using the update() function with multi=true param on mongolab platform. The problem is only the first item in the collection is updated.
The collection:
{
"_id": {
"$oid": "5454b446e4b02a012c939a0a"
},
"value": "1234",
"name": "first"
},
{
"_id": {
"$oid": "5454b446e4b02a012c939a0a"
},
"value": "1234",
"name": "second"
}
Script code:
$db->collection->update(
array('value' => '1234'),
array('$set' => array(
'name' => 'example name',
)),
array('multi' => true)
);
Result:
{
"_id": {
"$oid": "5454b446e4b02a012c939a0a"
},
"value": "1234",
"name": "example name"
},
{
"_id": {
"$oid": "5454b446e4b02a012c939a0a"
},
"value": "1234",
"name": "second"
}
The update() function accepts only three arrays as arguments.

Hi Yogesh,
I think your query should be:
db.collectionName.update({"value":"1234"},{$set:{"name":"example name"}},{'upsert':true, 'multiple': true});
The corresponding PHP codes would be:
<?php
$m = new MongoClient(); //connects to local mongo
$db_name = 'ri'; //replace database name you want to work with
$collection_name = 'brand_graph'; //replace collection name you want to work with
$select = $m->selectDB($db_name)->selectCollection($collection_name);
$where_array = array(
'value' => 1234
);
$update_data = array(
'$set' => array(
'name' => 'example name'
)
);
$options = array(
'upsert' => true,
'multiple' => true
);
$select->update($where_array, $update_data, $options);
?>
I hope this is what your were looking for.

I write below mongo query which update multiple documents but , I don't know how to convert this in PHP code but for reference you should use this query
db.collectionName.update({"value":"1234"},{$set:{"name":"example name"}},true,true)

Related

Using "aggregate" to combine a list of all subdocuments that match query?

I'm trying to use a PHP mongo library to "aggregate" on a data structure like this:
{
"_id": 100,
"name": "Joe",
"pets":[
{
"name": "Kill me",
"animal": "Frog"
},
{
"name": "Petrov",
"animal": "Cat"
},
{
"name": "Joe",
"animal": "Frog"
}
]
},
{
"_id": 101,
"name": "Jane",
"pets":[
{
"name": "James",
"animal": "Hedgehog"
},
{
"name": "Franklin",
"animal": "Frog"
}
}
For example, if I want to get all subdocuments where the animal is a frog. Note that I do NOT want all matching "super-documents" (i.e. the ones with _id). I want to get an ARRAY that looks like this:
[
{
"name": "Kill me",
"animal": "Frog"
},
{
"name": "Joe",
"animal": "Frog"
},
{
"name": "Franklin",
"animal": "Frog"
}
]
What syntax am I supposed to use (in PHP) to accomplish this? I know it has to do with aggregate, but I couldn't find anything that matches this specific scenario.
You can use below aggregation. $match to find documents where array has a value of Frog and $unwind the pets array. $match where document has Frog and final step is to group the matching documents into array.
<?php
$mongo = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$pipeline =
[
[
'$match' =>
[
'pets.animal' => 'Frog',
],
],
[
'$unwind' =>'$pets',
],
[
'$match' =>
[
'pets.animal' => 'Frog',
],
],
[
'$group' =>
[
'_id' => null,
'animals' => ['$push' => '$pets'],
],
],
];
$command = new \MongoDB\Driver\Command([
'aggregate' => 'insert_collection_name',
'pipeline' => $pipeline
]);
$cursor = $mongo->executeCommand('insert_db_name', $command);
foreach($cursor as $key => $document) {
//do something
}
?>

set a custom multiselect via JIRA REST API

I'm trying to set a custom field of type Multiselect via JIRA rest API using php. For reason I'm getting the following error:
{"errorMessages":[],"errors":{"Functionality Impacted":"expected 'value' property to be a string"}}
I have the following code for setting the custom field:
public function requestRemedy($summary, $description, $priority, $goliveDate,$startTime,
$endTime,$clientImpact,$impactedFunctionality,$fundTransfers ,$fieldAffected, $remedyChangeType,
$changeReason,$remedyImpact, $urgency,$riskLevel,$nameRequestor,$emailRequestor)
{
$json = Array ( "fields" => Array (
"project" => Array
( "id" => 10051 ),
"summary" => $summary,
"description" =>$description,
"issuetype" => Array ( "name" => "Remedy Change Management" ),
"priority" => Array("id" => $priority),
"customfield_13774" => $goliveDate,
"customfield_14408" => "$startTime",
"customfield_14409" => "$endTime",
"customfield_14412" => "$clientImpact",
"customfield_14908" =>Array ( 0 => Array(
"value" => ($impactedFunctionality),
)),
"customfield_14414" => Array("id" =>$fundTransfers),
// "customfield_14415" =>Array("id" => $businessOnline,"child" =>Array("id" => $businessDependency) ),
"customfield_14602" => Array("id" =>$fieldAffected),
"customfield_14422" => Array("id" =>$remedyChangeType),
"customfield_14423" => Array("id" =>$changeReason),
"customfield_14424" => Array("id" =>$remedyImpact),
"customfield_14425" => Array("id" =>$urgency),
"customfield_14426" => Array("id" =>$riskLevel),
"customfield_14700"=>$nameRequestor,
"customfield_14702"=>$emailRequestor
)
);
return $json;
}
After adding some dummy data to test the final structure of json, I get the following result:
{
"fields": {
"project": {
"id": 10051
},
"summary": "Test",
"description": "Human DeSC",
"issuetype": {
"name": "Remedy Change Management"
},
"priority": {
"id": "2"
},
"customfield_13774": "2016-11-08",
"customfield_14408": "2016-11-01T07:35:00.000+0200",
"customfield_14409": "2016-11-01T08:35:00.000+0200",
"customfield_14412": "cLIENT iMPACT",
"customfield_14908": [{
"value": ["Savings Accounts", "Current Accounts", "Call Deposits"]
}],
"customfield_14414": {
"id": "13647"
},
"customfield_14602": {
"id": "14022"
},
"customfield_14422": {
"id": "13712"
},
"customfield_14423": {
"id": "13718"
},
"customfield_14424": {
"id": "13722"
},
"customfield_14425": {
"id": "13726"
},
"customfield_14426": {
"id": "13730"
},
"customfield_14700": "Pastor Dan",
"customfield_14702": "email#time.com"
}
}
Which means the issue is here:
"customfield_14908": [{
"value": ["Savings Accounts", "Current Accounts", "Call Deposits"]
}],
the expected structure is:
"customfield_10008": [ {"value": "Savings Accounts" }, {"value": "Current Accounts" }, {"value": "Call Deposits" }]
Now I'm not sure how to build this using an associative array
The custom field I'm trying to set is customfield_14908. What I'm finding weird is that I used similar code for setting a multiselect field on JIRA version 7.2.1 and it works well, but not working on JIRA version 7.0.

how to create blank embedded document in mongodb by php

I want to initialize an object in mongodb like this
{"_id":"123","name":"JACK","data":{}}
array and map is the same thing in php, so when I save this
$a = [ 'name': 'JACK', 'data': [] ]
I got this
{ "_id": "123", "name": "JACK", "data": [] }
Question: how to create blank embedded document in mongodb by php
there are to different document
{ "_id": "123", "name": "JACK", "data": {} }
{ "_id": "123", "name": "JACK", "data": [] }
the same command in MongoDB shell will do different thing
db.test.update( { "name": "JACK" }, { "$set": { "data.5": 1 } } )
If you are beginning PHP with mongodb, you may want to take a look at this
If you want to represent this:
{
"_id":"123",
"name":"JACK",
"data":{}
}
You could do this in PHP:
$emptyObj = new \stdClass();
$doc = array(
'_id' => '123',
'name' => 'JACK',
'data' => $emptyObj
);

I can not get data to aggregate It. PHP + mongoDB

It works like I need:
$out = $collection->aggregate(
array(
'$match' => array('type' => 'chair')
),
array(
'$project' => array(
'chairtype' => 1,
'mijczjeqeo'=>1
)
),
array(
'$group' => array(
'_id' => '$chairtype',
'MIDDLE_mijczjeqeo' => array('$avg' => '$mijczjeqeo'),
'SUMMA__mijczjeqeo' => array('$sum' => '$mijczjeqeo')
)
)
);
my_dump($out);
But i need to get true data for aggregation from array in the same documents: versions[0][content][mijczjeqeo]
Please correct my script. It does not work:
$out = $collection->aggregate(
array(
'$match' => array('type' => 'chair')
),
array(
'$project' => array(
'chairtype' => 1,
'versions.0.content.mijczjeqeo'=>1
)
),
array(
'$group' => array(
'_id' => '$chairtype',
'MIDDLEmijczjeqeo' => array('$avg' => '$versions.0.content.mijczjeqeo'),
'SUMMAmijczjeqeo' => array('$sum' => '$versions[0]["content"]["mijczjeqeo"]')
)
)
);
no one method does not work:
'MIDDLEmijczjeqeo' => array('$avg' => '$versions.0.content.mijczjeqeo')
'SUMMAmijczjeqeo' => array('$sum' => '$versions[0]["content"]["mijczjeqeo"]')
I think the problem near .0.
I try to do it in mongo console...
db.documents.aggregate({$match:{'type':'chair'}},{$project:{'chairtype': 1, 'mijczjeqeo':1}},{$group:{'_id':'$chairtype','MID':{$avg:'$mijczjeqeo'}}})
{
"result" : [
{
"_id" : "T",
"MID" : 6.615384615384615
},
{
"_id" : "G",
"MID" : 8.310344827586206
},
{
"_id" : "E",
"MID" : 6.9523809523809526
}
],
"ok" : 1
}
db.documents.aggregate({$match:{'type':'chair'}},{$project:{'chairtype': 1, 'versions.0.content.mijczjeqeo':1}},{$group:{'_id':'$chairtype','MID':{$avg:'$versions.0.content.mijczjeqeo'}}})
{
"result" : [
{
"_id" : "T",
"MID" : 0
},
{
"_id" : "G",
"MID" : 0
},
{
"_id" : "E",
"MID" : 0
}
],
"ok" : 1
}
Well you cannot project like that in the aggregation pipeline. If you want to act on array elements within an aggregation statement you first need to $unwind the array and then either $match the required element(s) or as in your case choose the $first item using an additional $group stage.
Your question does not show the structure of a document so I'll just use a sample, as my "chairs" collection:
{
"_id": 1,
"type": "chair",
"chairtype": "A",
"versions": [
{
"revision": 1,
"content": {
"name": "ABC",
"value": 10
}
},
{
"revision": 2,
"content": {
"name": "BBB",
"value": 15
}
}
]
}
{
"_id": 2,
"type": "chair",
"chairtype": "A",
"versions": [
{
"revision": 1,
"content": {
"name": "CCC",
"value": 20
}
},
{
"revision": 2,
"content": {
"name": "BAB",
"value": 12
}
}
]
}
Minimal, but enough to get the point. Now the aggregate statement:
db.chairs.aggregate([
// Normal query matching, which is good
{ "$match": { "type": "chair" } },
// Unwind the array to de-normalize
{ "$unwind": "$versions" },
// Group by the document in order to get the "first" array element
{ "$group": {
"_id": "$_id",
"chairtype": { "$first": "$chairtype" },
"versions": { "$first": "$versions" }
}},
// Then group by "chairtype" to get your average values
{ "$group": {
"_id": "$chairtype",
"MID": {"$avg": "$versions.content.value"}
}}
])
Of course if your actual document has nested arrays then you will be "unwinding" and "matching" the required elements. But that is the general process of "narrowing down" the array contents to the elements you need.

mongodb-php update $pull

There is a collection "emailDeliveryActive":
{
"_id": ObjectId("4f1950f0e902edfc3e000001"),
"coupons": {
"4f1950b7e902edf23e000001": {
"_id": ObjectId("4f1950b7e902edf23e000001"),
"couponID": ObjectId("4f15c7d8e902edb667000000")
},
"4f1950bfe902ed843f000000": {
"_id": ObjectId("4f1950bfe902ed843f000000"),
"couponID": ObjectId("4f171f33e902ed4f4f000002")
}
},
"recipients": [
{
"email": "test1#gmail.com",
"get": "?auth=ZG1pdHJ5LnZvbG9zbmloaW5AZ21haWwuY29tfDA5OGY2YmNkNDYyMWQzNzNjYWRlNGU4MzI2MjdiNGY2"
},
{
"email": "test2#gmail.com",
"get": "?auth=ZGpyb3VibGVAZ21haWwuY29tfDA5OGY2YmNkNDYyMWQzNzNjYWRlNGU4MzI2MjdiNGY2"
},
{
"email": "test3#gmail.com",
"get": "?auth=a2FsaWJyb3YxQGdtYWlsLmNvbXwwOThmNmJjZDQ2MjFkMzczY2FkZTRlODMyNjI3YjRmNg=="
}
],
"title": "test"
}
Must be from an array of "recipients" to remove an item from a given email.
Doing so:
$result = $mongoDB->emailDeliveryActive->update(
array('_id' => $emailDelivery['_id']),
array(
'$pull'=>array(
'recipients.$.email' => 'test1#gmail.com'
)
)
);
$result in getting TRUE, but the collection does not change. I'm doing something wrong?
You don't need the $ operator- it is for the "position of the matched array item in the query"- doesn't make sense to use here. Try as:
$result = $mongoDB->emailDeliveryActive->update(
array('_id' => $emailDelivery['_id']),
array(
'$pull'=> array('recipients' => array('email' => 'test1#gmail.com'))
)
);

Categories