A sample collection
[
{
"_id":"id1",
"usersArray":[
{
"name":"user1Name",
"type":1
},
{
"name":"user2Name",
"type":1
},
{
"name":"user3Name",
"type":2
},
]
},
{
"_id":"id2",
"usersArray":[
{
"name":"user4Name",
"type":1
},
{
"name":"user5Name",
"type":3
},
{
"name":"user6Name",
"type":2
},
]
},
{
"_id":"id3",
"usersArray":[
{
"name":"user7Name",
"type":1
},
{
"name":"user8Name",
"type":1
},
{
"name":"user9Name",
"type":2
},
]
},
]
What I need is a filter that will return the documents with _id id1 and id3 since they have more than 1 objects in usersArray which have key-value pairs "type": 1
. It would be great if you could resolve this with just the filter.
CodePudding user response:
$expr
- Allow using aggregation operator.1.1.
$gt
- Filter the document with the result of 1.1.1 greater than 1.1.1.1.
$size
- Get the size of the result 1.1.1.1.1.1.1.1.
$filter
- Filter the document(s) withtype: 1
inusersArray
.
db.collection.find({
$expr: {
$gt: [
{
$size: {
$filter: {
input: "$usersArray",
cond: {
$eq: [
"$$this.type",
1
]
}
}
}
},
1
]
}
})
CodePudding user response:
Query
- make it set(
$union
with empty), get the $size - get the original $size
- if set size < original size => it contained duplicated type
*this is a way to do it not for type:1
duplicate only, this keeps documents that dont have duplicate same types, i am not sure what you need. (for example if type:2
is duplicated document wont pass the filter also)
aggregate(
[{"$match":
{"$expr":
{"$lt":
[{"$size": {"$setUnion": ["$usersArray.type", []]}},
{"$size": "$usersArray.type"}]}}}])