I have a collection like below :
`{
"topics" : [
{
"id" : "2",
"name" : "Test1",
"owner" : [
"123"
]
},
{
"id" : "3",
"name" : "Test2",
"owner" : [
"123",
"456"
]
}
]
}`
As, this data is in single document, and I want only matching elements based on their owner
, I am using below query ( using filter in aggregation ), but I am getting 0 matching elements.
Query :
Thanks in advance...!!
db.getCollection('topics').aggregate([
{"$match":{"topics.owner":{"$in":["123","456"]}}},
{"$project":{
"topics":{
"$filter":{
"input":"$topics",
"as":"topic",
"cond": {"$in": ["$$topic.owner",["123","456"]]}
}},
"_id":0
}}
])
This query should produce below output :
{
"topics" : [
{
"id" : "1",
"name" : "Test1",
"owner" : ["123"]
},
{
"id" : "2",
"name" : "Test2",
"owner" : ["123","456"]
}
]
}
CodePudding user response:
As the topic.owner
is an array, you can't use $in
directly as this compares whether the array is within in an array.
Instead, you should do as below:
$filter
- Filter the document in thetopics
array.1.1.
$gt
- Compare the result from 1.1.1 is greater than 0.1.1.1.
$size
- Get the size of the array from the result 1.1.1.1.1.1.1.1.
$setIntersection
- Intersect thetopic.owner
array with the input array.
{
"$project": {
"topics": {
"$filter": {
"input": "$topics",
"as": "topic",
"cond": {
$gt: [
{
$size: {
$setIntersection: [
"$$topic.owner",
[
"123",
"456"
]
]
}
},
0
]
}
}
},
"_id": 0
}
}
CodePudding user response:
db.getCollection('topics').aggregate([
{"$unwind":"$topics"},
{"$addFields":{
"rest":{"$or":[{"$in":["12z3","$topics.owner"]},{"$in":["456","$topics.owner"]}]}
}},
{"$match":{
"rest":true
}},
{"$group":{
"_id":"$_id",
"topics":{"$push":"$topics"}
}}
])