【问题标题】:How to count records with only a specific number of keys如何计算只有特定数量的键的记录
【发布时间】:2017-06-05 00:17:34
【问题描述】:

我在 MongoDB 中有一个用户模型如下所示:

{ _id: <some_id>,
  name: <some_name>,
  preferences: <this is an object with 1-20 key values pair>
}

我想获取所有首选项键都存在的用户数(首选项中有 20 个键的用户数。) 我该如何查询呢?

【问题讨论】:

    标签: mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    如果您拥有最新的 MongoDB 3.4,那么您可以使用 $objectToArray 在聚合语句中执行此操作:

    Model.aggregate([
      { "$group": {
        "_id": null,
        "count": {
          "$sum": {
            "$cond": {
              "if": { "$eq": [ 
                 { "$size": { 
                   "$objectToArray": { "$ifNull": [ "$preferences", { } ] }
                 }}, 
                 20
              ]},
              "then": 1,
              "else": 0
            }
          }
        }
      }}
    ])
    

    新的运算符$objectToArray 将采用“键/值”对的对象并将其转换为数组。所以这个:

     { "a": 1, "b": 2 }
    

    变成这样:

     [ { "k": "a", "v": 1 }, { "k": "b", "v": 2 } ]
    

    作为一个数组,您可以使用$size 等运算符来计算“键”的数量,该数量现在等于数组中的条目。

    对于早期版本,您可以在 JavaScript 评估中使用 $where 条件:

    Model.find(function() {
      return (this.hasOwnProperty("preferences")) ?
        Object.keys(this.preferences).length == 20 : false;
    }).count()
    

    后者并不是真正的“聚合”,但游标计数确实是您可以从 JavaScript 评估中获得的全部。

    【讨论】:

    • 如果某些键有空值会发生什么。我应该如何去消除那些?我想我可以在这里使用一些东西 stackoverflow.com/questions/33123396/… 但想知道你是否知道更优雅的东西?
    • @WABBIT0111 当然可以。您可以添加null 检查属性不存在的位置,该属性已添加到答案中。还是您在谈论“首选项”属性的“内部”键?在后一种情况下,您可以根据使用的操作添加$filter.filter() 操作。因此,我将后者解释为类似于{ "preferences": { "a": 1, "b": null } } 的意思,您在问如何“排除”“b”键,因为它的值是null?这真的归结为透视图,但简要浏览一下引用的链接,我想有什么比这更优雅。
    • 感谢您对这两种情况的详尽解释。我认为这两种情况都非常有用,我学到了很多东西。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 2013-07-22
    • 1970-01-01
    相关资源
    最近更新 更多