Lets say my collection looks like:
{
"_id" : ObjectId("6451529ad254d565bd12156b"),
"contentType" : "Json",
"fieldName" : "xxx",
"method" : "GET",
"value" : "Car",
}
{
"_id" : ObjectId("6451529ad254d565bd12156d"),
"contentType" : "Json",
"fieldName" : "xxx",
"method" : "GET",
"value" : "Plane",
}
{
"_id" : ObjectId("6451529ad254d565bd121570"),
"contentType" : "Json",
"fieldName" : "yyy",
"method" : "GET",
"value" : "Smile",
}
{
"_id" : ObjectId("6451529ad254d565bd12156b"),
"contentType" : "Empty",
"fieldName" : "zzz",
"method" : "POST",
"value" : "Train",
}
{
"_id" : ObjectId("6451529ad254d5651112156b"),
"contentType" : "Empty",
"fieldName" : "zzz",
"method" : "POST",
"value" : "Player",
}
{
"_id" : ObjectId("6451529ad254d565bd12156d"),
"contentType" : "Empty",
"fieldName" : "zzz",
"method" : "POST",
"value" : "Van",
}
{
"_id" : ObjectId("6451529ad254d565bd121570"),
"contentType" : "Json",
"fieldName" : "name4",
"method" : "GET",
"value" : "Van",
}
I'd like to request mongo with array and filter by inner elements of each array item, finally group by fieldName.
For example if I request:
[ {
method: GET,
contentType : Json,
fieldName: xxx,
} ,
{
method: POST,
contentType : Empty,
fieldName: zzz,
}
]
I want to have all objects with unique combination of
{ method: GET, contentType : Json , fieldName: xxx}
and aggregatin all values by fieldName: xxx
the response of this request should look like :
[ {
method: GET,
contentType : Json,
fieldName: xxx
values: ["Car", "Plane"] // here the aggregation by fieldName:xxx
} ,
{
method: POST,
contentType : Empty,
fieldName: zzz,
values: ["Player", "Train" ,"Van"] // here the aggregation by fieldName:zzz
}
]
tried to do like this but it didn't work
db.collection.aggregate([
{$match: {"$and": [{method: "GET"}, {contentType: 'Json'}, {fieldName: "xxx"}]}},
{$group: {values: "$fieldName"}}}
])
but I need it as array in input and return the same structure as request + aggregated values by fieldName preferably by Scala or Java
One option is to use an aggregation pipeline with a $filter
step::
db.collection.aggregate([
{$match: {
$expr: {$gt: [
{$size: {$filter: {
input: input,
cond: {$and: [
{$eq: ["$$this.method", "$method"]},
{$eq: ["$$this.contentType", "$contentType"]},
{$eq: ["$$this.fieldName", "$fieldName"]}
]}
}}},
0
]}
}},
{$group: {
_id: {
fieldName: "$fieldName",
contentType: "$contentType",
method: "$method"
},
values: {$push: "$value"}
}},
{$replaceRoot: {newRoot: {$mergeObjects: ["$_id", {values: "$values"}]}}}
])
See how it works on the playground example