问题
Look the following documents in a contacts collection on MongoDB 3.4:
{
"_id" : ObjectId("58f045526320ef24fc61fdb2"),
"name" : "John Doe",
"tags" : [
{
"name": "tagA",
"created_at": ISODate("2017-01-27T10:30:00Z")
},
{
"name": "tagB",
"created_at": ISODate("2017-01-28T13:30:00Z")
}
],
},
{
"_id" : ObjectId("58f045526320ef24fc61fdb3"),
"name" : "Johnny Doe",
"tags" : [
{
"name": "tagA",
"created_at": ISODate("2016-12-21T19:30:00Z")
},
{
"name": "tagC",
"created_at": ISODate("2017-01-28T13:30:00Z")
}
],
}
.
.
.
Is there any query using only find method (nor aggregate framework, nor $where) that can return:
- The contacts who have all the following tags: [tagA, tagC]
- The contacts who don't have all of these tags: [tagC, tagD]
- The contacts with all tags in 2017
Thanks in advanced
回答1:
I found a similar question at Check if every element in array matches condition.
To find the contacts who have all the following tags: [tagA, tagC]
, you can use a double negative to find the documents that do NOT have elements NOT in [tagA, tagC]
db.collection.find({"tags": {"$not": {"$elemMatch": {"name": {"$nin": ["tagA", "tagC"]}}}}})
To find the contacts who don't have all of these tags: [tagC, tagD]
db.collection.find({"tags": {"$elemMatch": {"name": {"$nin": ["tagC", "tagD"]}}}})
A similar query can be done for the date as well, although using $or
db.collection.find({"tags": {"$not": {"$elemMatch": {"$or": [
{"createdAt": {"$lt": ISODate("2017-01-01T00:00:00.000Z")}},
{"createdAt": {"$gt": ISODate("2017-12-31T23:59:59.999Z")}}]}}}})
来源:https://stackoverflow.com/questions/43472047/querying-array-of-objects-in-mongodb-using-only-find-method