从文档中获取子文档
getting subdocument from 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"
}
]
}
我想做的是根据它的 guid 获得某个部门,但到目前为止我没有找到任何干净的东西来获得我想要的文档。
我想得到这样的结果:
{
"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"
}
我一直在查看 mongodb 文档,但到目前为止没有任何效果,我得到的最接近的是使用 array_search,但我想直接从mongo 本身,如果可能的话,避免用 PHP.
对其进行黑客攻击
也许是这样的:
db.collection.find( { "Departments.Guid": "some_value" } )
https://docs.mongodb.com/manual/tutorial/query-embedded-documents/
假设 GUID 对于 Departments
数组中的子文档是唯一的(即查找 GUID 只会在父文档中产生一个可能的匹配项)但 GUID 可能在其他父文档中是相同的,那么这会产生您寻求的输出结果。如果 GUID 在所有数组和父文档中是唯一的,那么这也有效。
基本上,我们过滤 Departments.Guid
= 目标 GUID(下面是 "myGUID")。这给我们留下了一个 0 或 1 个元素的数组,我们从中提取带有 $arrayElemAt
的子文档,然后 "lift" 该文档作为根文档(而不是将文档分配给命名字段).如果没有子文档匹配(数组 post-filter 的长度为 0),那么 $arrayElemAt
会产生 null 而 qq
将不存在。我们想在调用 $replaceRoot
之前删除这些文档,这需要一个真实存在的字段才能提升到根目录中。
db.foo.aggregate([
{$project: { qq: {$arrayElemAt: [
{ $filter: {
input: "$Departments",
as: "zz",
cond: {$eq: [ "$$zz.Guid", "myGUID" ]}
}}
, 0] } }}
,{$match: { qq: {$exists: true}} }
,{$replaceRoot: { newRoot: "$qq"} }
]);
你可以试试这个,
db.foo.find({"_id" : ObjectId("59b0303bfe409a21fccc9523")})
.map(function(u){
return u.Departments
.filter(p => p.Guid == "D5950FC8-91B1-48A3-8B6A-F3A72FAC9175")
}
)
这只会 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"
}
]
]
我有一个包含子文档的集合,我正在尝试找到一种简单的方法来获取准确的文档。
{
"_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"
}
]
}
我想做的是根据它的 guid 获得某个部门,但到目前为止我没有找到任何干净的东西来获得我想要的文档。
我想得到这样的结果:
{
"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"
}
我一直在查看 mongodb 文档,但到目前为止没有任何效果,我得到的最接近的是使用 array_search,但我想直接从mongo 本身,如果可能的话,避免用 PHP.
对其进行黑客攻击也许是这样的:
db.collection.find( { "Departments.Guid": "some_value" } )
https://docs.mongodb.com/manual/tutorial/query-embedded-documents/
假设 GUID 对于 Departments
数组中的子文档是唯一的(即查找 GUID 只会在父文档中产生一个可能的匹配项)但 GUID 可能在其他父文档中是相同的,那么这会产生您寻求的输出结果。如果 GUID 在所有数组和父文档中是唯一的,那么这也有效。
基本上,我们过滤 Departments.Guid
= 目标 GUID(下面是 "myGUID")。这给我们留下了一个 0 或 1 个元素的数组,我们从中提取带有 $arrayElemAt
的子文档,然后 "lift" 该文档作为根文档(而不是将文档分配给命名字段).如果没有子文档匹配(数组 post-filter 的长度为 0),那么 $arrayElemAt
会产生 null 而 qq
将不存在。我们想在调用 $replaceRoot
之前删除这些文档,这需要一个真实存在的字段才能提升到根目录中。
db.foo.aggregate([
{$project: { qq: {$arrayElemAt: [
{ $filter: {
input: "$Departments",
as: "zz",
cond: {$eq: [ "$$zz.Guid", "myGUID" ]}
}}
, 0] } }}
,{$match: { qq: {$exists: true}} }
,{$replaceRoot: { newRoot: "$qq"} }
]);
你可以试试这个,
db.foo.find({"_id" : ObjectId("59b0303bfe409a21fccc9523")})
.map(function(u){
return u.Departments
.filter(p => p.Guid == "D5950FC8-91B1-48A3-8B6A-F3A72FAC9175")
}
)
这只会 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"
}
]
]