问题
I have a collection that has a sub-document in it and I'm trying to find an easy way to get an exact document.
{
"_id" : ObjectId("59b0303bfe409a21fccc9523"),
"CreatedOn" : ISODate("2017-07-22T15:55:00.000+0000"),
"UpdatedOn" : ISODate("2017-07-22T15:55:00.000+0000"),
"Guid" : "4F1D7541-FF27-4FEF-9BC4-CF27D2CB92BA",
"Company" : "Demo Co.",
"Departments" : [
{
"CreatedOn" : ISODate("2017-07-22T15:55:00.000+0000"),
"UpdatedOn" : ISODate("2017-07-22T15:55:00.000+0000"),
"Guid" : "D5950FC8-91B1-48A3-8B6A-F3A72FAC9175",
"Title" : "Execute"
}
]
}
what I'd like to do is get a certain department based on its guid but so far I'm not finding anything that is clean to get just the document I want.
I'd want to get a result like this:
{
"CreatedOn" : ISODate("2017-07-22T15:55:00.000+0000"),
"UpdatedOn" : ISODate("2017-07-22T15:55:00.000+0000"),
"Guid" : "D5950FC8-91B1-48A3-8B6A-F3A72FAC9175",
"Title" : "Execute"
}
I've been looking around the mongodb documentation but nothing is working so far, the closest I'm getting is using array_search, but I'd like to fetch it straight from mongo itself if possible to avoid hacking it with PHP.
回答1:
Perhaps something like this :
db.collection.find( { "Departments.Guid": "some_value" } )
https://docs.mongodb.com/manual/tutorial/query-embedded-documents/
回答2:
Assuming that the GUID is unique to the subdoc in the Departments
array (i.e. looking for a GUID yields ONLY one possible match in a parent doc) but GUIDs might be the same across OTHER parent docs, then this produces the output result you seek. If GUID is unique across all arrays AND parent docs, well then this works as well.
Basically, we filter for Departments.Guid
= target GUID (below is "myGUID"). This leaves us with an array of 0 or 1 elements, from which we extract the subdoc with $arrayElemAt
and then "lift" that doc into position as the root doc (as opposed to assigning the doc to a named field). If no subdoc matches (array post-filter is length 0), then $arrayElemAt
yields null and qq
will not exist. We want to eliminate these docs before calling $replaceRoot
which requires a real existing field to lift into the root.
db.foo.aggregate([
{$project: { qq: {$arrayElemAt: [
{ $filter: {
input: "$Departments",
as: "zz",
cond: {$eq: [ "$$zz.Guid", "myGUID" ]}
}}
, 0] } }}
,{$match: { qq: {$exists: true}} }
,{$replaceRoot: { newRoot: "$qq"} }
]);
回答3:
You can try out this,
db.foo.find({"_id" : ObjectId("59b0303bfe409a21fccc9523")})
.map(function(u){
return u.Departments
.filter(p => p.Guid == "D5950FC8-91B1-48A3-8B6A-F3A72FAC9175")
}
)
This will only return:
[
[
{
"CreatedOn" : ISODate("2017-07-22T21:25:00.000+05:30"),
"UpdatedOn" : ISODate("2017-07-22T21:25:00.000+05:30"),
"Guid" : "D5950FC8-91B1-48A3-8B6A-F3A72FAC9175",
"Title" : "Execute"
}
]
]
来源:https://stackoverflow.com/questions/47624171/getting-subdocument-from-document