Mongodb 如何查询特定文档的数组子集
Mongodb how can I query a subset of an array for a specific document
我想 运行 查询 select 特定文档。然后在每个文档上,打开一个子文档数组和 运行 一个查询来过滤这些子文档。
示例:
{
"_id" : ObjectID(23412351346435),
"list" : [
{date: ISODate(2015-01-12T00:00:00.000Z), name: "Jan 12"},
{date: ISODate(2015-01-13T00:00:00.000Z), name: "Jan 13"},
{date: ISODate(2015-01-14T00:00:00.000Z), name: "Jan 14"}
]
}
我想我可以用 Mongo 的 aggregate
功能做点什么。我已经能够匹配我想要的文档,但是我怎样才能在数组上进行子查询呢?我尝试使用 $elemMatch
,但只有 return 是数组中与日期范围匹配的第一项。
当我查询 ObjectID(23412351346435)
和日期范围 2015-01-12 到 2015-01-13 时要清楚,我希望它 return this;
{
"_id" : ObjectID(23412351346435),
"list" : [
{date: ISODate(2015-01-12T00:00:00.000Z), name: "Jan 12"},
{date: ISODate(2015-01-13T00:00:00.000Z), name: "Jan 13"}
]
}
您可以使用 $unwind 运算符。它允许您在文档中获取一个数组,并使用每个数组元素克隆该文档。然后你就可以在场上比赛了。如有必要,您可以使用 $group 将文档备份。
[
{$match:{...}},
{$unwind:"myfield"},
{$match:{"myfield.name":"Jan 12"}},
{$group:{ _id:"$id", "myfield":{$push:"$myfield"} }}
]
请注意,$unwind 对于大型文档集来说很慢,对于多个数组来说是组合的。这是 Mongo 2.4.x 的唯一选择。重新排列数据可能会更好,这样您就没有数组。
如您所料,您可以使用 aggregation
来获得您要查找的结果。您需要在 aggregation pipeline 中执行的步骤如下。
您的查询应如下所示:
db.collection.aggregate([
{ "$match": { "_id": ObjectId("54ef8b0acfb269d664de0b48")} },
{ "$unwind": "$list" },
{ "$match": {
"list.date": { $gte: ISODate("2015-01-12T00:00:00.000Z"),
$lte: ISODate("2015-01-13T00:00:00.000Z")
}
}},
{ "$group": {
"_id": "$_id",
"list": { "$push": { "date": "$list.date", "name": "$list.name" }}
}}
]);
我想 运行 查询 select 特定文档。然后在每个文档上,打开一个子文档数组和 运行 一个查询来过滤这些子文档。
示例:
{
"_id" : ObjectID(23412351346435),
"list" : [
{date: ISODate(2015-01-12T00:00:00.000Z), name: "Jan 12"},
{date: ISODate(2015-01-13T00:00:00.000Z), name: "Jan 13"},
{date: ISODate(2015-01-14T00:00:00.000Z), name: "Jan 14"}
]
}
我想我可以用 Mongo 的 aggregate
功能做点什么。我已经能够匹配我想要的文档,但是我怎样才能在数组上进行子查询呢?我尝试使用 $elemMatch
,但只有 return 是数组中与日期范围匹配的第一项。
当我查询 ObjectID(23412351346435)
和日期范围 2015-01-12 到 2015-01-13 时要清楚,我希望它 return this;
{
"_id" : ObjectID(23412351346435),
"list" : [
{date: ISODate(2015-01-12T00:00:00.000Z), name: "Jan 12"},
{date: ISODate(2015-01-13T00:00:00.000Z), name: "Jan 13"}
]
}
您可以使用 $unwind 运算符。它允许您在文档中获取一个数组,并使用每个数组元素克隆该文档。然后你就可以在场上比赛了。如有必要,您可以使用 $group 将文档备份。
[
{$match:{...}},
{$unwind:"myfield"},
{$match:{"myfield.name":"Jan 12"}},
{$group:{ _id:"$id", "myfield":{$push:"$myfield"} }}
]
请注意,$unwind 对于大型文档集来说很慢,对于多个数组来说是组合的。这是 Mongo 2.4.x 的唯一选择。重新排列数据可能会更好,这样您就没有数组。
如您所料,您可以使用 aggregation
来获得您要查找的结果。您需要在 aggregation pipeline 中执行的步骤如下。
您的查询应如下所示:
db.collection.aggregate([
{ "$match": { "_id": ObjectId("54ef8b0acfb269d664de0b48")} },
{ "$unwind": "$list" },
{ "$match": {
"list.date": { $gte: ISODate("2015-01-12T00:00:00.000Z"),
$lte: ISODate("2015-01-13T00:00:00.000Z")
}
}},
{ "$group": {
"_id": "$_id",
"list": { "$push": { "date": "$list.date", "name": "$list.name" }}
}}
]);