Laravel MongoDB - aggregation, ordering query
up vote
1
down vote
favorite
I am wondering how could I achieve a specific result.
Starting of
I am using https://github.com/jenssegers/laravel-mongodb
The code sample below is used to get an array of documents that contains my specific slug in the rewards node. And till that point, everything works as intended.
$array = [
'rewards.slug' => ['$eq' => 'example_slug'],
'expired' => ['$gte' => CarbonCarbon::now()->toDateTimeString()]
];
$models = Master::raw(function ($collection) use (&$array) {
return $collection->find(
$array, ["typeMap" => ['root' => 'array', 'document' => 'array']])
->toArray();
});
My example document
{
"_id": {
"$oid": "5be4464eafad20007245543f"
},
"some_int_value": 100,
"some_string_value": "String",
"rewards": [
{
"slug": "example_slug",
"name": "Example slug",
"quantity": 4,
"estimated": {
"value": 18750
}
},
{
"slug": "example_slug",
"name": "Example slug",
"quantity": 1,
"estimated": {
"value": 100
}
},
{
"slug": "other_example",
"name": "Other slug example",
"quantity": 1,
"estimated": {
"value": 100
}
}
],
"expires": "2018-11-08 20:20:45",
}
Desired result
I would like to implement some more complex query, which would do the following.
- Retrieve documents that : pseudo
select all documents that contain reward "slug": "example_slug", sum the quantity of them, return greater than X quantity documents, order by sum quantity desc
- and a very similar one to the above
select all documents that contain reward "slug": "example_slug", sum estimated.value, return greater than X estimated.value documents, order by sum of estimated.value desc
If you do need more explanation feel free to ask, I feel like I don't even know where to start with this one.
All help is greatly appreciated
mongodb laravel laravel-5 aggregation-framework jenssegers-mongodb
add a comment |
up vote
1
down vote
favorite
I am wondering how could I achieve a specific result.
Starting of
I am using https://github.com/jenssegers/laravel-mongodb
The code sample below is used to get an array of documents that contains my specific slug in the rewards node. And till that point, everything works as intended.
$array = [
'rewards.slug' => ['$eq' => 'example_slug'],
'expired' => ['$gte' => CarbonCarbon::now()->toDateTimeString()]
];
$models = Master::raw(function ($collection) use (&$array) {
return $collection->find(
$array, ["typeMap" => ['root' => 'array', 'document' => 'array']])
->toArray();
});
My example document
{
"_id": {
"$oid": "5be4464eafad20007245543f"
},
"some_int_value": 100,
"some_string_value": "String",
"rewards": [
{
"slug": "example_slug",
"name": "Example slug",
"quantity": 4,
"estimated": {
"value": 18750
}
},
{
"slug": "example_slug",
"name": "Example slug",
"quantity": 1,
"estimated": {
"value": 100
}
},
{
"slug": "other_example",
"name": "Other slug example",
"quantity": 1,
"estimated": {
"value": 100
}
}
],
"expires": "2018-11-08 20:20:45",
}
Desired result
I would like to implement some more complex query, which would do the following.
- Retrieve documents that : pseudo
select all documents that contain reward "slug": "example_slug", sum the quantity of them, return greater than X quantity documents, order by sum quantity desc
- and a very similar one to the above
select all documents that contain reward "slug": "example_slug", sum estimated.value, return greater than X estimated.value documents, order by sum of estimated.value desc
If you do need more explanation feel free to ask, I feel like I don't even know where to start with this one.
All help is greatly appreciated
mongodb laravel laravel-5 aggregation-framework jenssegers-mongodb
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I am wondering how could I achieve a specific result.
Starting of
I am using https://github.com/jenssegers/laravel-mongodb
The code sample below is used to get an array of documents that contains my specific slug in the rewards node. And till that point, everything works as intended.
$array = [
'rewards.slug' => ['$eq' => 'example_slug'],
'expired' => ['$gte' => CarbonCarbon::now()->toDateTimeString()]
];
$models = Master::raw(function ($collection) use (&$array) {
return $collection->find(
$array, ["typeMap" => ['root' => 'array', 'document' => 'array']])
->toArray();
});
My example document
{
"_id": {
"$oid": "5be4464eafad20007245543f"
},
"some_int_value": 100,
"some_string_value": "String",
"rewards": [
{
"slug": "example_slug",
"name": "Example slug",
"quantity": 4,
"estimated": {
"value": 18750
}
},
{
"slug": "example_slug",
"name": "Example slug",
"quantity": 1,
"estimated": {
"value": 100
}
},
{
"slug": "other_example",
"name": "Other slug example",
"quantity": 1,
"estimated": {
"value": 100
}
}
],
"expires": "2018-11-08 20:20:45",
}
Desired result
I would like to implement some more complex query, which would do the following.
- Retrieve documents that : pseudo
select all documents that contain reward "slug": "example_slug", sum the quantity of them, return greater than X quantity documents, order by sum quantity desc
- and a very similar one to the above
select all documents that contain reward "slug": "example_slug", sum estimated.value, return greater than X estimated.value documents, order by sum of estimated.value desc
If you do need more explanation feel free to ask, I feel like I don't even know where to start with this one.
All help is greatly appreciated
mongodb laravel laravel-5 aggregation-framework jenssegers-mongodb
I am wondering how could I achieve a specific result.
Starting of
I am using https://github.com/jenssegers/laravel-mongodb
The code sample below is used to get an array of documents that contains my specific slug in the rewards node. And till that point, everything works as intended.
$array = [
'rewards.slug' => ['$eq' => 'example_slug'],
'expired' => ['$gte' => CarbonCarbon::now()->toDateTimeString()]
];
$models = Master::raw(function ($collection) use (&$array) {
return $collection->find(
$array, ["typeMap" => ['root' => 'array', 'document' => 'array']])
->toArray();
});
My example document
{
"_id": {
"$oid": "5be4464eafad20007245543f"
},
"some_int_value": 100,
"some_string_value": "String",
"rewards": [
{
"slug": "example_slug",
"name": "Example slug",
"quantity": 4,
"estimated": {
"value": 18750
}
},
{
"slug": "example_slug",
"name": "Example slug",
"quantity": 1,
"estimated": {
"value": 100
}
},
{
"slug": "other_example",
"name": "Other slug example",
"quantity": 1,
"estimated": {
"value": 100
}
}
],
"expires": "2018-11-08 20:20:45",
}
Desired result
I would like to implement some more complex query, which would do the following.
- Retrieve documents that : pseudo
select all documents that contain reward "slug": "example_slug", sum the quantity of them, return greater than X quantity documents, order by sum quantity desc
- and a very similar one to the above
select all documents that contain reward "slug": "example_slug", sum estimated.value, return greater than X estimated.value documents, order by sum of estimated.value desc
If you do need more explanation feel free to ask, I feel like I don't even know where to start with this one.
All help is greatly appreciated
mongodb laravel laravel-5 aggregation-framework jenssegers-mongodb
mongodb laravel laravel-5 aggregation-framework jenssegers-mongodb
edited Nov 10 at 22:09
Veeram
37.3k33057
37.3k33057
asked Nov 8 at 17:54
Kavvson Empcraft
117323
117323
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
You can use below aggregation in 3.6.
$addFields
to create an extra slugcount
field to hold the result.
$filter
rewards with slug matching example_slug
followed by $sum
to sum the quantity
field.
$match
with $gt > X
- aggregation expression to filter documents where the sum of all matching quantities is greater than X
$sort
slugcount desc and $project
with exclusion to remove the slugcount from the final response.
db.colname.aggregate([
{"$addFields":{
"slugcount":
{"$let":{
"vars":{
"mslug":{
"$filter":{
"input":"$rewards",
"cond":{"$eq":["$$this.slug","example_slug"]}
}
}
},
"in":{"$sum":"$$mslug.quantity"}
}}
}},
{"$match":{"slugcount":{"$gt":X}}},
{"$sort":{"slugcount":-1}},
{"$project":{"slugcount":0}}
])
Something like
ModelName::raw(function ($collection) {
return $collection->aggregate([
['$match' => ['expired' => ['$gte' => CarbonCarbon::now()->toDateTimeString()]]],
['$addFields' => [
'slugcount'
['$let' => [
'vars' => [
'mslug' => [
'$filter' => [
'input' => '$rewards',
'cond' => ['$eq' => ['$$this.slug','example_slug']]
]
]
],
'in' => ['$sum' => '$$mslug.quantity']
]]
]],
['$match' => ['slugcount'=> ['$gt' => X]]],
['$sort' => ['slugcount' => -1]],
['$project' => ['slugcount' => 0]]]);
});
You can replace quantity
with estimated.value
for second aggregation.
You want those operators single quoted, yes? Eg'$gt'
not"$gt"
.
– bishop
Nov 10 at 22:21
1
@bishop yes thanks. updated.
– Veeram
Nov 10 at 22:24
Will take a look on that shortly :)
– Kavvson Empcraft
Nov 10 at 22:53
I feel like we are missing the '$gte' => CarbonCarbon::now()->toDateTimeString() else it seems right, could you update the answer with that :)
– Kavvson Empcraft
Nov 10 at 23:09
in 17h I can award the bounty thanks :)
– Kavvson Empcraft
Nov 11 at 0:26
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
You can use below aggregation in 3.6.
$addFields
to create an extra slugcount
field to hold the result.
$filter
rewards with slug matching example_slug
followed by $sum
to sum the quantity
field.
$match
with $gt > X
- aggregation expression to filter documents where the sum of all matching quantities is greater than X
$sort
slugcount desc and $project
with exclusion to remove the slugcount from the final response.
db.colname.aggregate([
{"$addFields":{
"slugcount":
{"$let":{
"vars":{
"mslug":{
"$filter":{
"input":"$rewards",
"cond":{"$eq":["$$this.slug","example_slug"]}
}
}
},
"in":{"$sum":"$$mslug.quantity"}
}}
}},
{"$match":{"slugcount":{"$gt":X}}},
{"$sort":{"slugcount":-1}},
{"$project":{"slugcount":0}}
])
Something like
ModelName::raw(function ($collection) {
return $collection->aggregate([
['$match' => ['expired' => ['$gte' => CarbonCarbon::now()->toDateTimeString()]]],
['$addFields' => [
'slugcount'
['$let' => [
'vars' => [
'mslug' => [
'$filter' => [
'input' => '$rewards',
'cond' => ['$eq' => ['$$this.slug','example_slug']]
]
]
],
'in' => ['$sum' => '$$mslug.quantity']
]]
]],
['$match' => ['slugcount'=> ['$gt' => X]]],
['$sort' => ['slugcount' => -1]],
['$project' => ['slugcount' => 0]]]);
});
You can replace quantity
with estimated.value
for second aggregation.
You want those operators single quoted, yes? Eg'$gt'
not"$gt"
.
– bishop
Nov 10 at 22:21
1
@bishop yes thanks. updated.
– Veeram
Nov 10 at 22:24
Will take a look on that shortly :)
– Kavvson Empcraft
Nov 10 at 22:53
I feel like we are missing the '$gte' => CarbonCarbon::now()->toDateTimeString() else it seems right, could you update the answer with that :)
– Kavvson Empcraft
Nov 10 at 23:09
in 17h I can award the bounty thanks :)
– Kavvson Empcraft
Nov 11 at 0:26
add a comment |
up vote
1
down vote
accepted
You can use below aggregation in 3.6.
$addFields
to create an extra slugcount
field to hold the result.
$filter
rewards with slug matching example_slug
followed by $sum
to sum the quantity
field.
$match
with $gt > X
- aggregation expression to filter documents where the sum of all matching quantities is greater than X
$sort
slugcount desc and $project
with exclusion to remove the slugcount from the final response.
db.colname.aggregate([
{"$addFields":{
"slugcount":
{"$let":{
"vars":{
"mslug":{
"$filter":{
"input":"$rewards",
"cond":{"$eq":["$$this.slug","example_slug"]}
}
}
},
"in":{"$sum":"$$mslug.quantity"}
}}
}},
{"$match":{"slugcount":{"$gt":X}}},
{"$sort":{"slugcount":-1}},
{"$project":{"slugcount":0}}
])
Something like
ModelName::raw(function ($collection) {
return $collection->aggregate([
['$match' => ['expired' => ['$gte' => CarbonCarbon::now()->toDateTimeString()]]],
['$addFields' => [
'slugcount'
['$let' => [
'vars' => [
'mslug' => [
'$filter' => [
'input' => '$rewards',
'cond' => ['$eq' => ['$$this.slug','example_slug']]
]
]
],
'in' => ['$sum' => '$$mslug.quantity']
]]
]],
['$match' => ['slugcount'=> ['$gt' => X]]],
['$sort' => ['slugcount' => -1]],
['$project' => ['slugcount' => 0]]]);
});
You can replace quantity
with estimated.value
for second aggregation.
You want those operators single quoted, yes? Eg'$gt'
not"$gt"
.
– bishop
Nov 10 at 22:21
1
@bishop yes thanks. updated.
– Veeram
Nov 10 at 22:24
Will take a look on that shortly :)
– Kavvson Empcraft
Nov 10 at 22:53
I feel like we are missing the '$gte' => CarbonCarbon::now()->toDateTimeString() else it seems right, could you update the answer with that :)
– Kavvson Empcraft
Nov 10 at 23:09
in 17h I can award the bounty thanks :)
– Kavvson Empcraft
Nov 11 at 0:26
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
You can use below aggregation in 3.6.
$addFields
to create an extra slugcount
field to hold the result.
$filter
rewards with slug matching example_slug
followed by $sum
to sum the quantity
field.
$match
with $gt > X
- aggregation expression to filter documents where the sum of all matching quantities is greater than X
$sort
slugcount desc and $project
with exclusion to remove the slugcount from the final response.
db.colname.aggregate([
{"$addFields":{
"slugcount":
{"$let":{
"vars":{
"mslug":{
"$filter":{
"input":"$rewards",
"cond":{"$eq":["$$this.slug","example_slug"]}
}
}
},
"in":{"$sum":"$$mslug.quantity"}
}}
}},
{"$match":{"slugcount":{"$gt":X}}},
{"$sort":{"slugcount":-1}},
{"$project":{"slugcount":0}}
])
Something like
ModelName::raw(function ($collection) {
return $collection->aggregate([
['$match' => ['expired' => ['$gte' => CarbonCarbon::now()->toDateTimeString()]]],
['$addFields' => [
'slugcount'
['$let' => [
'vars' => [
'mslug' => [
'$filter' => [
'input' => '$rewards',
'cond' => ['$eq' => ['$$this.slug','example_slug']]
]
]
],
'in' => ['$sum' => '$$mslug.quantity']
]]
]],
['$match' => ['slugcount'=> ['$gt' => X]]],
['$sort' => ['slugcount' => -1]],
['$project' => ['slugcount' => 0]]]);
});
You can replace quantity
with estimated.value
for second aggregation.
You can use below aggregation in 3.6.
$addFields
to create an extra slugcount
field to hold the result.
$filter
rewards with slug matching example_slug
followed by $sum
to sum the quantity
field.
$match
with $gt > X
- aggregation expression to filter documents where the sum of all matching quantities is greater than X
$sort
slugcount desc and $project
with exclusion to remove the slugcount from the final response.
db.colname.aggregate([
{"$addFields":{
"slugcount":
{"$let":{
"vars":{
"mslug":{
"$filter":{
"input":"$rewards",
"cond":{"$eq":["$$this.slug","example_slug"]}
}
}
},
"in":{"$sum":"$$mslug.quantity"}
}}
}},
{"$match":{"slugcount":{"$gt":X}}},
{"$sort":{"slugcount":-1}},
{"$project":{"slugcount":0}}
])
Something like
ModelName::raw(function ($collection) {
return $collection->aggregate([
['$match' => ['expired' => ['$gte' => CarbonCarbon::now()->toDateTimeString()]]],
['$addFields' => [
'slugcount'
['$let' => [
'vars' => [
'mslug' => [
'$filter' => [
'input' => '$rewards',
'cond' => ['$eq' => ['$$this.slug','example_slug']]
]
]
],
'in' => ['$sum' => '$$mslug.quantity']
]]
]],
['$match' => ['slugcount'=> ['$gt' => X]]],
['$sort' => ['slugcount' => -1]],
['$project' => ['slugcount' => 0]]]);
});
You can replace quantity
with estimated.value
for second aggregation.
edited Nov 11 at 1:15
answered Nov 10 at 22:08
Veeram
37.3k33057
37.3k33057
You want those operators single quoted, yes? Eg'$gt'
not"$gt"
.
– bishop
Nov 10 at 22:21
1
@bishop yes thanks. updated.
– Veeram
Nov 10 at 22:24
Will take a look on that shortly :)
– Kavvson Empcraft
Nov 10 at 22:53
I feel like we are missing the '$gte' => CarbonCarbon::now()->toDateTimeString() else it seems right, could you update the answer with that :)
– Kavvson Empcraft
Nov 10 at 23:09
in 17h I can award the bounty thanks :)
– Kavvson Empcraft
Nov 11 at 0:26
add a comment |
You want those operators single quoted, yes? Eg'$gt'
not"$gt"
.
– bishop
Nov 10 at 22:21
1
@bishop yes thanks. updated.
– Veeram
Nov 10 at 22:24
Will take a look on that shortly :)
– Kavvson Empcraft
Nov 10 at 22:53
I feel like we are missing the '$gte' => CarbonCarbon::now()->toDateTimeString() else it seems right, could you update the answer with that :)
– Kavvson Empcraft
Nov 10 at 23:09
in 17h I can award the bounty thanks :)
– Kavvson Empcraft
Nov 11 at 0:26
You want those operators single quoted, yes? Eg
'$gt'
not "$gt"
.– bishop
Nov 10 at 22:21
You want those operators single quoted, yes? Eg
'$gt'
not "$gt"
.– bishop
Nov 10 at 22:21
1
1
@bishop yes thanks. updated.
– Veeram
Nov 10 at 22:24
@bishop yes thanks. updated.
– Veeram
Nov 10 at 22:24
Will take a look on that shortly :)
– Kavvson Empcraft
Nov 10 at 22:53
Will take a look on that shortly :)
– Kavvson Empcraft
Nov 10 at 22:53
I feel like we are missing the '$gte' => CarbonCarbon::now()->toDateTimeString() else it seems right, could you update the answer with that :)
– Kavvson Empcraft
Nov 10 at 23:09
I feel like we are missing the '$gte' => CarbonCarbon::now()->toDateTimeString() else it seems right, could you update the answer with that :)
– Kavvson Empcraft
Nov 10 at 23:09
in 17h I can award the bounty thanks :)
– Kavvson Empcraft
Nov 11 at 0:26
in 17h I can award the bounty thanks :)
– Kavvson Empcraft
Nov 11 at 0:26
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53213521%2flaravel-mongodb-aggregation-ordering-query%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown