将单独的查询结果合并为一个结果
Posted
技术标签:
【中文标题】将单独的查询结果合并为一个结果【英文标题】:Merge Separate Query Results into One Result 【发布时间】:2017-10-23 23:10:16 【问题描述】:我有以下疑问:
db.orders.find( currency: 'ils' ).sort( percent: -1 ).limit(1);
db.orders.find( currency: 'usd' ).sort( percent: -1 ).limit(1);
db.orders.find( currency: 'eur' ).sort( percent: -1 ).limit(1);
我想获得一个包含这些查询结果的 3 个文档的结果。换句话说,将结果合并为一个结果。知道怎么做吗?
【问题讨论】:
【参考方案1】:将.aggregate()
和$group
与$first
一起使用,以$sort
开头:
db.orders.aggregate([
"$match":
"currency": "$in": [ "ils", "usd", "eur" ]
,
"$sort": "currency": 1, "percent": -1 ,
"$group":
"_id": "$currency",
"doc": "$first": "$$ROOT"
])
如果需要,"doc"
可以选择 $project
或 $replaceRoot
($project
要求您“明确”命名所需的所有文档属性):
db.orders.aggregate([
"$match":
"currency": "$in": [ "ils", "usd", "eur" ]
,
"$sort": "currency": 1, "percent": -1 ,
"$group":
"_id": "$currency",
"doc": "$first": "$$ROOT"
,
"$replaceRoot": "newRoot": "$doc"
])
基本概念是 $in
对于单个属性参数的工作方式类似于 $or
,并且实际上是较长语句的“简写”。这会选择文档中提供的许多“任何”值,而不会选择其他值。
在“长”形式中,$or
实际上是:
"$or": [
"currency": "ils" ,
"currency": "usd" ,
"currency": "eur"
]
所以您现在可以更清楚地看到它就像“编写三个查询,因为您得到“this” OR “that” OR “the other” 作为所选结果的组成部分。
$sort
与您所做的大致相同,除了您在“货币”前加上“前缀”,考虑到您正在获取所有提供的内容,而不仅仅是一个。
$first
自然地从分组边界获取第一个文档内容,即“货币”。我们可以提供$$ROOT
来替代在$first
累加器的参数中单独命名所有文档属性。
【讨论】:
哇,谢谢你的回答!这是对数据库的单个请求吗?哪些索引可以提高查询效率? @Naor 查询中有一个一个字段,即"currency"
。聚合管道不能在第一阶段以外的任何阶段使用索引。从 MongoDB 3.6 开始,我们可以“提示”查询,以确保在 $sort
阶段中的 "percent"
也被拾取,如果您在这两个字段上有一个复合索引,则按照显示的顺序。以上是关于将单独的查询结果合并为一个结果的主要内容,如果未能解决你的问题,请参考以下文章