[英]How to retrieve only a subset of an array of embedded documents in MongoDB?
I am new to MongoDB and I am having trouble retrieving only a subset of an array of embedded documents.我是 MongoDB 的新手,我无法仅检索嵌入式文档数组的子集。 For instance, I have the following documents:例如,我有以下文件:
{
"_id": "Stock1",
"data": [{"value": 10.0, "date": "2000-01-01T00:00:00.000Z"},
{"value": 12.0, "date": "2010-01-01T00:00:00.000Z"},
{"value": 14.0, "date": "2020-01-01T00:00:00.000Z"}]
},
{
"_id": "Stock2",
"data": [{"value": 10.0, "date": "2000-01-01T00:00:00.000Z"},
{"value": 8.0, "date": "2010-01-01T00:00:00.000Z"},
{"value": 6.0, "date": "2020-01-01T00:00:00.000Z"}]
},
{
"_id": "Stock3",
"data": [{"value": 10.0, "date": "2000-01-01T00:00:00.000Z"},
{"value": 10.0, "date": "2010-01-01T00:00:00.000Z"},
{"value": 10.0, "date": "2020-01-01T00:00:00.000Z"}]
}
And I would like to retrieve data
between date
2010-01-01 and 2020-01-01 (included) of "Stock1" and "Stock3", ie I would like to end up with this:我想检索“Stock1”和“Stock3”的date
2010-01-01 和 2020-01-01(包括)之间的data
,即我想得到这个:
{
"_id": "Stock1",
"data": [{"value": 12.0, "date": "2010-01-01T00:00:00.000Z"},
{"value": 14.0, "date": "2020-01-01T00:00:00.000Z"}]
},
{
"_id": "Stock3",
"data": [{"value": 10.0, "date": "2010-01-01T00:00:00.000Z"},
{"value": 10.0, "date": "2020-01-01T00:00:00.000Z"}]
}
I have tried the find
command:我试过find
命令:
{"_id": {$in: ["Stock1", "Stock3"]}, "data.date": {$gte: ISODate('2010-01-01'), $lte: ISODate('2020-01-01')}}
But I am retrieving all dates, which is undesirable.但我正在检索所有日期,这是不可取的。
I am aware of the aggregate
command but I am unsure of how to construct the pipeline.我知道aggregate
命令,但我不确定如何构建管道。 Can someone pinpoint me on how I should proceed?有人可以指出我应该如何进行吗?
Any help would be greatly appreciated!任何帮助将不胜感激!
$unwind
- Descontruct data
array to documents. $unwind
- 将data
数组解构为文档。$match
- Filter based on id
and date range for data.date
. $match
- 根据data.date
的id
和日期范围进行过滤。$group
- Group by id
(Reverse for Step 1). $group
- 按id
分组(与第 1 步相反)。db.collection.aggregate([
{
$unwind: "$data"
},
{
$match: {
$expr: {
$and: [
{
$in: [
"$_id",
[
"Stock1",
"Stock3"
]
]
},
{
$gte: [
{
$toDate: "$data.date"
},
ISODate("2010-01-01")
]
},
{
$lte: [
{
$toDate: "$data.date"
},
ISODate("2020-01-01")
]
}
]
}
}
},
{
$group: {
"_id": "$_id",
"data": {
$push: "$data"
}
}
}
])
Sample Solution 1 on Mongo Playground Mongo Playground 上的示例解决方案 1
$match
- Filter document(s) based on _id
. $match
- 根据_id
过滤文档。$project
- Display the document with $filter
data array. $project
- 显示带有$filter
数据数组的文档。db.collection.aggregate([
{
$match: {
"_id": {
$in: [
"Stock1",
"Stock3"
]
}
}
},
{
$project: {
"_id": 1,
"data": {
"$filter": {
"input": "$data",
"cond": {
"$and": [
{
$gte: [
{
$toDate: "$$this.date"
},
ISODate("2010-01-01")
]
},
{
$lte: [
{
$toDate: "$$this.date"
},
ISODate("2020-01-01")
]
}
]
}
}
}
}
}
])
Sample Solution 2 on Mongo Playground Mongo Playground 上的示例解决方案 2
You can use $elemMatch
:您可以使用$elemMatch
:
{"_id": {$in: ["Stock1", "Stock3"]}, "data":{$elemMatch:{date: {$gte: ISODate('2010-01-01'), $lte: ISODate('2020-01-01')}}}}
A Single Nested Document Meets Multiple Query Conditions on Nested Fields单个嵌套文档满足嵌套字段的多个查询条件
Use $elemMatch operator to specify multiple criteria on an array of embedded documents such that at least one embedded document satisfies all the specified criteria.使用 $elemMatch 运算符对一组嵌入文档指定多个条件,以便至少一个嵌入文档满足所有指定条件。
Source: https://docs.mongodb.com/manual/tutorial/query-array-of-documents/资料来源: https://docs.mongodb.com/manual/tutorial/query-array-of-documents/
To avoid $unwind
and $group
you can use $filter
in an aggregate query like this:为了避免$unwind
和$group
你可以在这样的聚合查询中使用$filter
:
db.collection.aggregate([
{
"$match": {
"_id": {
"$in": ["Stock1","Stock3"]
}
}
},
{
"$project": {
"data": {
"$filter": {
"input": "$data",
"as": "d",
"cond": {
"$and": [
{
"$gte": [{"$toDate": "$$d.date"},ISODate("2010-01-01")]
},
{
"$lte": [{"$toDate": "$$d.date"},ISODate("2020-01-01")]
}
]
}
}
}
}
}
])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.