将单独的查询结果合并为一个结果

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" 也被拾取,如果您在这两个字段上有一个复合索引,则按照显示的顺序。

以上是关于将单独的查询结果合并为一个结果的主要内容,如果未能解决你的问题,请参考以下文章

将 2 个内部连接结果合并为一个结果

将两个 SQL 查询的结果组合为单独的列

mybatis查询结果如何合并为列表

如何将查询结果保存到单独的表中?

在 db2 中合并两个 select 语句的结果

如何将三个选择查询合并为一个,以在 Oracle 中实现如下所需的结果?