MongoDB - PHP modifying array's object values - php

I have a field which stores an array of objects. I want to modify the object's "status" value depending on the "id" value the object possesses.
"authors" : [
{
"id" : "18",
"first_name" : "Buddhika",
"last_name" : "Chathuranga",
"$$hashKey" : "object:35",
"status" : NumberLong(0)
},
{
"id" : "3", // search for this number
"first_name" : "Pasindu",
"last_name" : "Priyanath",
"$$hashKey" : "object:43",
"status" : NumberLong(0) // modify this to 1
}
],

We can leverage positional update in MongoDB to update values inside array.
Mongo Positional Update
Please find script below.
db.authors.update(
{"authors.id": "3"},
{ $set: { "authors.$.status" : NumberLong(1) }}
)

Update in Mongo DB php:
db.collection.update( criteria, objNew, upsert, multi );
Detail Explanation

Related

PHP Multi Array Merging JSON

I've got JSON output that comes to me like this
{ [objects{}] [to] [from] [total] }
and due to the API I'm pulling this from I can only pull 500 records at a time, what I'm trying to do is merge the objects part of multiple json outputs into a larger recordset.
I've tried using array_merge with json_encode and json_decode but it's not working, I'm assuming it's because of the other arrays (to/from/total) that are impacting my ability to merge.
Any idea how I could go about this, I was thinking of a line by line merge, but issue with this is different types of arrays have different elements (I'm only trying to merge arrays with the same elements).
Edit: hmmm json formatting didn't come through well even with code tags
{
"objects" : [ {
"uid" : "f7534a54-fd17-4bc2-9a26-8a567082cc86",
"name" : "host_10.1.1.1",
"type" : "host",
"domain" : {
"uid" : "8fe7e918-8530-4a7d-851c-bf8a7c3889c9",
"name" : "Lab-Ext_VPN",
"domain-type" : "domain"
},
"ipv4-address" : "10.1.1.1"
}, {
"uid" : "1ba63e41-4d2c-48ea-a970-66a806089ff5",
"name" : "host_10.1.1.10",
"type" : "host",
"domain" : {
"uid" : "8fe7e918-8530-4a7d-851c-bf8a7c3889c9",
"name" : "Lab-Ext_VPN",
"domain-type" : "domain"
},
"ipv4-address" : "10.1.1.10"
}, {
"uid" : "d798b126-25de-4138-b25d-b1edfe83d259",
"name" : "host_10.1.1.100",
"type" : "host",
"domain" : {
"uid" : "8fe7e918-8530-4a7d-851c-bf8a7c3889c9",
"name" : "Lab-Ext_VPN",
"domain-type" : "domain"
},
"ipv4-address" : "10.1.1.100"
}, {
"uid" : "247e1b2e-a45d-457e-87f7-78a6acdeea9f",
"name" : "host_10.1.1.101",
"type" : "host",
"domain" : {
"uid" : "8fe7e918-8530-4a7d-851c-bf8a7c3889c9",
"name" : "Lab-Ext_VPN",
"domain-type" : "domain"
},
"ipv4-address" : "10.1.1.101"
}, {
"uid" : "381e59a0-2094-422a-b538-8f607ec58384",
"name" : "host_10.1.1.102",
"type" : "host",
"domain" : {
"uid" : "8fe7e918-8530-4a7d-851c-bf8a7c3889c9",
"name" : "Lab-Ext_VPN",
"domain-type" : "domain"
},
"ipv4-address" : "10.1.1.102"
} ],
"from" : 1,
"to" : 5,
"total" : 614
`
You have 4 elements in the given json, object to from and total
I am assuming, you hav to merge the object from two JSONs, get minimum value of from, get maximum value from to and sum of total
function my_merge($json_1,$json_2){
$array_1 = json_decode($json_1,true);
$array_2 = json_decode($json_2,true);
return ['objects'=>array_merge($array_1['objects'],$array_2['objects']),'from'=>min($array_1['from'],$array_2['from']),'to'=>max($array_1['to'],$array_2['to']),'total'=>($array_1['total']+$array_2['total'])];
}
Above, first, json_decode with second parameter true to decode and convert JSON to array.
Second, merge the index [0] of both $array_1 and $array_2 as it contains the object. Do the min max and summation for total and return the resultant array.

conversion to PHP, update and insert in subdocument

I am having trouble converting the statement to php
Here is the structure of the data:
db.rooms.find({"_id" : "1620888265"}).pretty();
{
"_id" : "1620888265",
"start" : 1620988265,
"end" : null,
"users" : [
{
"name" : "owner",
"score" : 0.9,
"singin" : 1620895469
},
{
"name" : "user",
"singin" : 1620895769
}
],
"questions" : [
{
"id": 1
"title" : "X",
"released" : false
}
]
}
Here the command that works for me:
db.rooms.updateOne({"_id" : "1620970325obn","questions.ident":2},{$set : {"questions.$.released":true,"questions.$.time":'1415'}});
Once translated to PHP (not working for me):
$rooms_db->updateOne(array("_id" => $room,"questions.ident"=>$ident), array ('$set'=>array('questions.$.released' => true,'questions.$.time'=>$time)));
The problem has been that the variable "$ident" was a number, but for some reason PHP treated it as a String. This can be seen with var_dump ($ident) .
"questions.ident"=>(int)$ident), this fixed the problem

Sorting array/sub document in mongodb PHP based on datetime [duplicate]

This question already has answers here:
Mongodb and sorting sub array
(2 answers)
Closed 5 years ago.
I am stuck at a point where i need to sort the documents based on the date time field following is my database structure
"_id" : ObjectId("59199bbb05b505777d86e9a2"),
"Email" : "sk.sagarkhan95#gmail.com",
"BlogPosts" : [
{
"PostID" : 7,
"Title" : "Party Time",
"Name" : "Sagar Khan",
"Description" : "Farewell party with 2k17 batchmates at atmosphere 4... #AllNight #Fun #CHEERS....",
"Date" : ISODate("2017-05-15T13:18:01Z"),
"Image" : "users/sk.sagarkhan95#gmail.com/pictures/prof-pic.jpg",
"Likes" : [
"hs#gmail.com",
"shweta#gmail.com",
"ankita#gmail.com",
"sk.sagarkhan95#gmail.com"
],
"Comments" : [
{
"CommentID" : 4,
"email" : "hs#gmail.com",
"Name" : "Harish Shinde",
"Image" : "users/hs#gmail.com/pictures/prof-pic.jpg",
"comment" : "Yo... Cheers ",
"Time" : ISODate("2017-05-15T13:18:40Z")
}
]
}
]}
{
"_id" : ObjectId("59450ce02aa01e3027df57be"),
"Email" : "hs#gmail.com",
"BlogPosts" : [
{
"PostID" : 2,
"Title" : "At Goa",
"Name" : "Harish Shinde",
"Description" : "Relaxing at baga Beach Goa ",
"Date" : ISODate("2017-06-17T11:05:20Z"),
"Image" : "users/hs#gmail.com/pictures/prof-pic.jpg",
"Likes" : [
"sk.sagarkhan95#gmail.com"
],
"Comments" : [ ]
}
]
}
Now i want to sort the documents in descending order based on Date in the BlogPosts array.
In Mongodb Console i tried
db.Timeline.find().sort({BlogPosts.Date : -1 }).pretty()
But In PHP i am not able to do this
I tried
$cursor = $collection->find()->sort(array("BlogPosts"=>array("Date"=> -1)));
and
$cursor = $collection->find()->sort(array("BlogPosts.$.Date"=> -1 ));
I also tried the solution mentioned in this answer but no luck... Please help me out
Instead of:
sort(array("BlogPosts.$.Date"=> -1 ));
try
sort(array("BlogPosts.Date"=> -1 ));
Refer this question

Elasticsearch GeoMapping with PHP not working

I have the following mapping in Elasticsearch 2.2
"clinics" : {
"mappings" : {
"clinic" : {
"properties" : {
"address_1" : {
"type" : "string",
"analyzer" : "standard"
},
"city" : {
"type" : "string"
},
"country" : {
"type" : "string"
},
"id" : {
"type" : "long"
},
"location" : {
"type" : "geo_point"
},
"name" : {
"type" : "string",
"analyzer" : "standard"
},
"state" : {
"type" : "string"
},
"zipcode" : {
"type" : "string",
"analyzer" : "standard"
}
}
}
}
},
I am using PHP to add to the index with Elastiquent5. my toArray() is:
public function toArray()
{
$array = parent::toArray();
$object = new \stdClass();
$object->lat = $array['latitude'];
$object->lon = $array['longitude'];
$array['location'] = $object;
return $array;
}
When I try to add the item to the index i get the following error:
{"error":{"root_cause":[{"type":"remote_transport_exception","reason":"[Solarman][10.0.2.15:9300][indices:data/write/index[p]]"}],"type":"illegal_argument_exception","reason":"[location] is defined as an object in mapping [clinics] but this name is already used for a field in other types"},"status":400}
In json format it yields correctly, in php array it is:
array:10 [
"name" => "Clinic A"
"address_1" => "123 Main St"
"city" => "NY"
"state" => "NY"
"zipcode" => "11111"
"country" => "US"
"id" => 6968
"location" => {#526
+"lat": 45.2116373
+"lon": -72.1891546
}
]
If I manually json_encode this and use the curl -XPUT 'http://localhost:9200' -d ''
it goes through - however the PHP doesnt. Any idea where I went wrong?
clarification
My goal is to insert the coordinate that my model data is extracting to map to the location field inside the index since I already designed as a geo_point type as defined by my mapping
I do not want to designate a new field in order to solve this. Secondary note: as I mentioned doing a put with the json will yield successfully however not as a php object out with the php drivers for elastic search which yielded the error when it tried to create the document
As mentioned in the error message, [location] is defined as an object in mapping [clinics] but this name is already used for a field in properties. Changing the variable name like the following might work.
public function toArray()
{
$array = parent::toArray();
$object = new \stdClass();
$object->lat = $array['latitude'];
$object->lon = $array['longitude'];
$array['location_ob'] = $object;
return $array;
}

How to update subdocument into an array using MongoDB in Codeigniter?

I'm using Codeigniter 3.0.6, with this MongoDB Library https://github.com/intekhabrizvi/Codeigniter-mongo-library
What i'm trying to do is to update fields in a subdocument of this following committees array with ObjectId("570f6e08407729ec3000002b")
{
"_id" : ObjectId("570f4a94407729d42e00002e"),
"name" : "Test Community",
"committees" : [
{
"_id" : ObjectId("570f6e08407729ec3000002b"),
"name" : "2016",
"start" : ISODate("2016-01-17T00:00:00.000Z"),
"end" : ISODate("2016-12-12T00:00:00.000Z"),
"join_state" : 1,
"state" : 1
},
{
"_id" : ObjectId("570f6e08407729ec3000002c"),
"name" : "2017",
"start" : ISODate("2017-01-17T00:00:00.000Z"),
"end" : ISODate("2017-12-12T00:00:00.000Z"),
"join_state" : 1,
"state" : 1
}
]}
But using above library or can you suggest me some other way to make it work right. Please don't mention mongodb command lines, as i'm aware about it. So it would be great if you can help me with PHP code, or codeigniter way is very much appreciable.

Categories