Laravel collection formatting key to field - php

I have a laravel collection that has this format:
{
"24385528032901": [
{
"time": "2020-06-30T22:30:00.000000Z",
"conso_prod": "Prod",
"meter_id": "24385528032901",
"delta": "0",
},
{
"time": "2020-06-30T23:00:00.000000Z",
"conso_prod": "Prod",
"meter_id": "24385528032901",
"delta": "2",
}
],
"24385528032777": [
{
"time": "2020-06-30T22:30:00.000000Z",
"conso_prod": "Prod",
"meter_id": "24385528032777",
"delta": "0",
},
{
"time": "2020-06-30T23:00:00.000000Z",
"conso_prod": "Prod",
"meter_id": "24385528032777",
"delta": "5",
}
], etc.
}
I'm having an hard time converting it to a chartJS linechart graph format:
[
[
'label' => '24385528032901',
'data' => $measures->map->delta,
], [
'label' => '24385528032777',
'data' => $measures->map->delta,
],
]
I know there is a collection method to do this, but can't find it anymore. Anyone ?

If i got your question right and you want to get meter_id and delta as label and data you can get meter_id and delta fields only from your collection then use collection's map helper to map these fields to your new field names like so
Model::get(['meter_id', 'delta'])->map(function (Model $model) {
return [
'label' => $model->meter_id,
'data' => $model->delta,
];
})->toArray()

Related

How to search in elastic search in array of objects?

I have structure in my es doc like :
"urls": {
"de": [
{
"page_type": 3,
"language_id": 13,
"url": "some/watteninseln/"
},
{
"page_type": 5,
"language_id": 13,
"url": "none/watteninseln/"
}
],
"pt": [
{
"page_type": 3,
"language_id": 22,
"url": "some/west-frisian-islands/"
}
]
}
And I want to be able get this doc with params
url and language
so,
$query[] =
[
"bool" => [
"minimum_should_match" => 1,
"should" => [
[
"exists" => [
"field" => 'urls.' . $filters['lang']. $filters['url']
]
],
]
]
];
Im trying like this, but it will be work if we have associative in key urls. But I need to find value in array of objects
Could someone tell me correct way to do it ?

Retrieving data from two collections in MongoDB with PHP having _id as a value already

I'm trying to use aggregate to return token and kyc_status in an API call.
I have below data in tokens collection
{
"_id": {
"$oid": "5fca628feb1f03d82c76e85f"
},
"user_id": "5fca62d0eb1f03d82c76e860",
"token": "token_here",
"valid_till": "2021-01-03",
"created": "2020-12-04 20:27:05",
"modified": "2020-12-04 20:27:05"
}
then I have below data in users collection
{
"_id": {
"$oid": "5fca62d0eb1f03d82c76e860"
},
"seller_type_id": "",
"status": {
"$numberInt": "1"
},
"kyc_status": "pending",
"username": "user_name",
"password": "password_here",
"email": "email_here",
"primary_contact": "primary",
"secondary_contact": "secondary"
}
Now i have id 5fca62d0eb1f03d82c76e860 in $user_id PHP variable
I'm using the below code to achieve to show kyc_status and token
$result = $collection->aggregate( [
[ '$lookup' => [
'from' => 'users',
'localField' => '_id',
'foreignField' => 'user_id',
'as' => 'user_role'
]
],
[ '$unwind' => '$user_info' ],
[
'$project' => [ 'kyc_staus' => '$user_info.kyc_status' ]
]
]
);
I do not get any out put when I print the $result variable it shows me a whole lot of data but does not show what I want, I searched and tried most of StackOverflow answers to the same but did not get any.
Can anyone let me know where i am goring wrong / what should i do to get the desired output?

How do I extract subdocument in laravel mongodb

Hello Good Developers,
I am using jenssegers/laravel-mongodb package to query my MongoDB from Laravel.
Here's Fiddle for my query: https://mongoplayground.net/p/qzbNN8Siy-3
I have following JSON
[{
"id": "GLOBAL_EDUCATION",
"general_name": "GLOBAL_EDUCATION",
"display_name": "GLOBAL_EDUCATION",
"profile_section_id": 0,
"translated": [
{
"con_lang": "US-EN",
"country_code": "US",
"language_code": "EN",
"text": "What is the highest level of education you have completed?",
"hint": null
},
{
"con_lang": "US-ES",
"country_code": "US",
"language_code": "ES",
"text": "\u00bfCu\u00e1l es su nivel de educaci\u00f3n?",
"hint": null
}...
{
....
}
]
I am trying to run following command
db.collection.find({ 'id': "GLOBAL_EDUCATION" },{_id:0, id:1, general_name:1, translated:{ $elemMatch: {con_lang: "US-EN"} }})
Expecting result like this
[
{
"general_name": "GLOBAL_EDUCATION",
"id": "GLOBAL_EDUCATION",
"translated": [
{
"con_lang": "US-EN",
"country_code": "US",
"hint": null,
"language_code": "EN",
"text": "What is the highest level of education you have completed?"
}
]
}
]
Everything is fine while query directly in MoDB but issue arise when I am trying this in Laravel.
I've tried every possible known function from MongoDB package. but Not able to do this.
here's my Array
$findArray = [
[
'id' => "GLOBAL_EDUCATION",
],
[
'_id' => 0,
'id' => 1,
'general_name' => 1,
'translated' => [
'$elemMatch' => ['con_lang' => "US-EN"]
],
]
];
$model = GlobalQuestions::raw()->find($findArray) //OR
$data = GlobalQuestions::raw(function($collection) use ($findArray){
return $collection->find($findArray);
});
What I am doing wrong here, is this kind of Find() not possible here and I've to do this by aggregation?
Since no-one answered this, I am posting the solution if someone is having the same issue.
Doing some more R&D on the same I was able to do this using where and Project as well by Aggregation Pipelines.
----- Using Where() and Project() ------
$projectArray = [
'_id' => 0,
'id' => 1,
'general_name' => 1,
'translated' => [
'$elemMatch' => ['con_lang' => "FR-FR"]
],
];
$data = GlobalQuestions::where('id', '=', 'GLOBAL_EDUCATION')
->project($projectArray)
->get();
--- Using Aggregation and $unwind ---
$data = GlobalQuestions::raw(function($collection) {
return $collection->aggregate([
[
'$match' => [
'id' => "GLOBAL_EDUCATION"
]
],
[
'$unwind' => '$translated',
],
[
'$match' => [
'translated.con_lang' => "US-EN"
]
],
[
'$project' => [
'_id'=> 0,
'id'=> 1,
'general_name' => 1,
'translated' => 1,
]
]
]);
})->first();

date comparison returning incorrect results

I'm trying to return records that fall under a specific range but it seems that the wrong records are returned, this issue does not occur when I opt to use the $lt condition alone.
Below is the returned json
{
"_id": {
"$oid": "5a5528c471872a00ee77731d"
},
"histories": [
{
"created": "2017-09-21T08:24:18.716+0100",
"items": [
{
"field": "status",
"fieldtype": "jira",
"fieldId": "status",
"from": "10007",
"fromString": "With Testing",
"to": "10012",
"toString": "Completed"
}
]
},
{
"created": "2017-10-27T15:10:58.179+0100",
"items": [
{
"field": "status",
"fieldtype": "jira",
"fieldId": "status",
"from": "10007",
"fromString": "With Testing",
"to": "10012",
"toString": "Completed"
}
]
}
]
}
Below is the aggregate pipeline being used with commented out attempts.
'pipeline' => [
[
'$match' => [
'histories.created' => [
'$gte' => '2017-09-28T00:00:00Z+0100',
'$lt' => '2017-10-04T00:00:00Z+0100'
//'$gte' => '2017-09-28T00:00:00Z',
//'$lt' => '2017-10-04T00:00:00Z'
//'$gte' => '2017-09-28',
//'$lt' => '2017-10-04'
]
]
]
]
The mongo collection I'm querying has no histories.created with a value between 2017-09-28 to 2017-10-04 so I should an empty json from the above query instead of one record
{}
I'm not sure what I'm doing wrong, I tried converting the date strings in to UTCDateTime objects but I still get the same results
I'm using mongodb with php

What should be the mongoDb query to find number of occurrences?

Sample records in the collection,
(doc 1)
[{
"_id": ObjectId("567941aaf0058ed6755ab3dc"),
"hash_count": NumberInt(7),
"time": [
NumberInt(1450787170),
NumberInt(1450787292),
NumberInt(1450787307),
NumberInt(1450787333),
NumberInt(1450787615)
],
"word": "batman"
},
(doc 2)
{
"_id": ObjectId("567941aaf0058ed6755ab3dc"),
"hash_count": NumberInt(7),
"time": [
NumberInt(1450787170),
NumberInt(1450787292),
NumberInt(1450787307),
NumberInt(1450787333),
NumberInt(1450787354),
NumberInt(1450787526),
NumberInt(1450787615)
],
"word": "apple"
}]
Have stored using PHP,
I want to find the number of records in between time (1450787307) and (1450787615)
Answer:
apple=5
batman=3
What should be query for it?
I ran this command
{
aggregate : "hashtags",
pipeline:
[
{$match:{"time":{$gte:NumberInt(1450787307), $lte:NumberInt(1450787615)}}},
{$unwind:"$time"},
{$match:{"time":{$gte:NumberInt(1450787307), $lte:NumberInt(1450787615)}}},
{$group:{"_id":"$word","count":{$sum:1}}}
]
}
which gave this result
Response from server:
{
"result": [
],
"ok": 1
}
Since you are stuck with an older version of mongoDB, you cannot leverage the power of the array aggregation operators introduced in 3.2.
You would have to aggregate as below:
db.collection.aggregate([
{$match:{"time":{$gte:NumberInt(1450787307), $lte:NumberInt(1450787615)}}},
{$unwind:"$time"},
{$match:{"time":{$gte:NumberInt(1450787307), $lte:NumberInt(1450787615)}}},
{$group:{"_id":"$word","count":{$sum:1}}}
])
translated to PHP,
$result = $c->aggregate([
[ '$match' => [ 'time' => [ '$gte' => NumberInt(1450787307),
'$lte' => NumberInt(1450787615) ] ] ],
[ '$unwind' => '$time' ],
[ '$match' => [ 'time' => [ '$gte' => NumberInt(1450787307),
'$lte' => NumberInt(1450787615) ] ] ],
[ '$group' => [ '_id' => '$word', 'count' => [ '$sum' => 1 ] ] ]
]);
In version 3.2, you could use the combination of $filter and $size to acheive the same result and with less expensive operations.
db.collection.aggregate([
{$match:{"time":{$gte:NumberInt(1450787307),
$lte:NumberInt(1450787615)}}},
{$project:{"_id":0,"word":1,
"count":{$size:{$filter:
{"input":"$time",
"as":"t",
"cond":{$and:[
{$gte:["$$t",NumberInt(1450787307)]},
{$lte:["$$t",NumberInt(1450787615)]}]}
}
}
}
}}
])
ok , after trying a lot I have come with this answer and is correct
for
1450787615- lower limit
1450855155- upper limit
db.hashtags.aggregate([
{
"$match": {
"time": {
"$gte": 1450787615, "$lte": 1450855155
}
}
},
{ "$unwind": "$time" },
{
"$match": {
"time": {
"$gte": 1450787615, "$lte": 1450855155
}
}
},
{
"$group": {
"_id": "$word",
"count": {
"$sum": 1
}
}
}
])
answer is like
{
"result" : [
{
"_id" : "batman",
"count" : 3
},
{
"_id" : "dear",
"count" : 1
},
{
"_id" : "ghost",
"count" : 1
}
],
"ok" : 1
}
db.collection.find({time:{$gt: 1450787307, $lt: 1450787615}});
This will first give you a cursor of all docs that fit within your given time range. Once you have that you can iterate through the cursor and print out the name as well as some loop logic to find the number of occurences for each one. I've only lightly worked with mongodb so there may be a more efficient way to do this.
reference:
https://docs.mongodb.org/v3.0/reference/method/db.collection.find/

Categories