【问题标题】:Get min and max value in single query in mongodb在mongodb的单个查询中获取最小值和最大值
【发布时间】:2018-11-26 18:05:30
【问题描述】:

考虑“单词”中的以下文档:

[{
  _id: 1,
  usages: 2,
  word: "Name"
}, {
  _id: 2,
  usages: 1,
  word: "Street"
}, {
  _id: 3,
  usages: 1,
  word: "House"
}, {
  _id: 4,
  usages: 3,
  word: "Table"
}, {
  _id: 5,
  usages: 3,
  word: "Bread"
}, {
  _id: 6,
  usages: 4,
  word: "Door"
}]

如何获取使用次数最低或最高的所有记录?最低应返回 id 2 和 3(及其单词),最高应返回 id 6 及其单词。

我需要将这些数据聚合成随机数量的最低/最高记录(准确地说是 50 个),因此它需要是一个聚合。

它应该是单次查找,因此使用 $max 或 $min 的另一个查询无法找到最小值/最大值。

MongoDB 版本是 3.4.7,Mongoose 版本是 5.0.0-rc1。不需要 Mongoose 解决方案,因为我可以使用原始查询。 (但它是首选!)

例子:

Words.aggregate([ 
  { 
    $match: { _
      usages: { WHAT_SHOULD_I_HAVE_HERE }
    }
  }, { 
    $sample: { 
      size: 50 
    } 
  }
])

谢谢!

【问题讨论】:

    标签: mongodb mongoose aggregation-framework aggregate


    【解决方案1】:

    你可以试试下面的聚合

    $facet 将为您提供usages 的两个最低和最高值,您可以使用$filter 运算符轻松地通过它们$project

    db.collection.aggregate([
      { "$facet": {
        "minUsages": [{ "$sort": { "usages": -1 } }],
        "maxUsages": [{ "$sort": { "usages": 1 } }]
      }},
      { "$addFields": {
        "lowestUsages": {
          "$arrayElemAt": ["$minUsages", 0]
        },
        "highestUsages": {
          "$arrayElemAt": ["$maxUsages", 0]
        }
      }},
      { "$project": {
        "minUsages": {
          "$filter": {
            "input": "$minUsages",
            "as": "minUsage",
            "cond": {
              "$eq": ["$$minUsage.usages", "$lowestUsages.usages"]
            }
          }
        },
        "maxUsages": {
          "$filter": {
            "input": "$maxUsages",
            "as": "maxUsage",
            "cond": {
              "$eq": ["$$maxUsage.usages", "$highestUsages.usages"]
            }
          }
        }
      }}
    ])
    

    或者您也可以使用find 查询来完成此操作

    const minUsage = await db.collection.find({}).sort({ "usages": -1 }).limit(1)
    const maxUsage = await db.collection.find({}).sort({ "usages": 1 }).limit(1)
    
    const minUsages = await db.collection.find({ "usages": { "$in": [minUsages[0].usages] } })
    const maxUsages = await db.collection.find({ "usages": { "$in": [maxUsages[0].usages] } })
    

    看看here

    【讨论】:

    • 您的聚合工作完美!尽管您仍然添加了具有 2 个或 4 个查询的方法。你认为 find 方法比聚合方法更快吗?
    猜你喜欢
    • 2018-12-27
    • 2022-11-25
    • 2021-11-08
    • 1970-01-01
    • 2019-03-13
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多