首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MongoDB文档嵌套文档筛选

MongoDB文档嵌套文档筛选
EN

Stack Overflow用户
提问于 2017-02-08 18:30:27
回答 1查看 2.9K关注 0票数 3

我在和MongoDb打架

我有一个文档集合,其中单个文档的结构如下

代码语言:javascript
运行
复制
{
    "_id": { "$oid": "588a931d5c98fe0f3f84d93f" },
    "name": "Michele",
    "type": "F",
    "category": "G",
    "meta":{
        "code": "113835667",
        "updated": {"$date": "2017-02-07T00:00:00.000Z"},
        "since": {"$date": "2013-11-07T23:00:00.000Z"}
    },
    "data": [
        {
          "date": {"$date": "2013-11-07T23:00:00.000Z"},
          "close": 12.23
        }
        ... // removed 
        {
          "date": {"$date": "2017-02-07T00:00:00.000Z"},
          "close": 15.22
        }
    ]
}

我需要做的是返回具有匹配日期的文档,但是从数据数组中过滤掉_id属性不在指定时间范围内的文档。

这就是我从现在开始的尝试

代码语言:javascript
运行
复制
 let id;    //[DocumentId]
 let from;  //[Date]
 let to;    //[Date]
 collection.aggregate([
            { $match: { _id: { $eq: id } } },
            { $unwind: '$data' },
            { $match: { 'data.date': { $gte: from, $lte: to } } },
            { $group: { _id: '$_id', 
                        data: { $push: { date:'$data.date', close: '$data.close' } } } }
        ], ...);

这种方法的问题是,我返回的文档只包含_id和数据属性,数据过滤结果是可以的,而我需要返回完整的可用属性集。

非常感谢您的建议!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-10 14:26:45

如果你可以升级到Mongo 3.4 (最新的稳定版本),这可以做得很好:

代码语言:javascript
运行
复制
db.collection.aggregate([
        //Pre-filter to have data arrays with at least one matching date
	{$match: {_id: id, 'data.date': {$gte: from, $lte: to}}},
        //Filter the items array
	{
		$addFields: {
			'items': {
				$filter: {
					input: '$data', as: 'item', cond: {
						$and: [
							{$gte: ["$$item.date", from]},
							{$lte: ["$$item.date", to]}
						]
					}
				}
			}
		}
	}
]);

如果你必须保持mongo 3.2,我唯一能想到的就是像这样使用$ROOT:

代码语言:javascript
运行
复制
db.collection.aggregate([
	{$match: {_id: id, 'data.date': {$gte: from, $lte: to}}},
	{
		$project: {
			'filteredData': {
				$filter: {
					input: '$data', as: 'item', cond: {
						$and: [
							{$gte: ["$$item.date", from]},
							{$lte: ["$$item.date", to]}
						]
					}
				}
			},
			'originalDocument': '$$ROOT'
		}
	}
]);

结果对象将具有originalDocument和filteredData属性,您需要在服务器代码中处理它们(实际上是一个循环)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42110650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档