在mongodb中

时间:2018-06-17 20:27:22

标签: mongodb mongoose aggregation-framework aggregate

考虑以下文件" Words":

[{
  _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 
    } 
  }
])

谢谢!

1 个答案:

答案 0 :(得分:2)

您可以尝试以下聚合

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

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