Reputation: 64326
I have mongodb rows with array element which looks like this:
{"data" : [1, 111]}
{"data" : [222, 1]}
{"data" : [1, 333]}
{"data" : [2, 444]}
How to get unique array elements by "master" element. So for example "master" element is 1 I should get result: [111, 222, 333]
and not 444
, because that array does not contain 1. If master element would be 2, the result should be: [444]
I tried something like this aggregation. Is it correct? Are there any performance issues? What indecies should be on table to make it fast?
[
{$match: {"data": 1}},
{$project : {a : '$data'}},
{$unwind: '$a'},
{$group: {_id: 'a', items: {$addToSet: '$a'}}}
]
Upvotes: 1
Views: 60
Reputation: 8705
I think this works also
{"_id" 1}
is like group by null, all make it true, just added to have the master key as _id (on the group $$REMOVE
system variable is used to not add the master key)Query (where you see 1 put your master key, or a variable)
db.collection.aggregate([
{
"$match": {
"data": 1
}
},
{
"$unwind": {
"path": "$data"
}
},
{
"$group": {
"_id": 1,
"members": {
"$addToSet": {
"$cond": [
{
"$ne": [
"$data",
1
]
},
"$data",
"$$REMOVE"
]
}
}
}
}
])
Upvotes: 1
Reputation: 20354
You can use Aggregation
framework:
$match
to filter all documents that have "master" key in the "data" array.$group
to concatenate "data" arrays of all documents in one property called "result" and $filter
to filter our "master" element from "data" arrays. ("result" will be an array that will have all documents "data" arrays as elements).$reduce
with $concatArrays
to concatenate all "data" arrays inside "result" property.db.collection.aggregate([
{
"$match": {
data: 1
}
},
{
"$group": {
"_id": null,
result: {
$addToSet: {
"$filter": {
"input": "$data",
"cond": {
"$ne": [
"$$this",
1
]
}
}
}
}
}
},
{
"$project": {
result: {
$reduce: {
input: "$result",
initialValue: [],
in: {
$concatArrays: [
"$$value",
"$$this"
]
}
}
}
}
}
])
Be aware that the "master" element has to be dynamically populated in first stage for $match
pipeline, as well as in the second stage when performing filtering with $filter
operator.
Here is the working example: https://mongoplayground.net/p/EtYwOqAE-PE
Upvotes: 1