【问题标题】:Mongo sort on a calculated conditionMongo在计算条件下排序
【发布时间】:2016-01-02 16:30:58
【问题描述】:

我有一个 Mongo 消息集合,如下所示:

{
  'recipients': [],
  'unRead': [],
  'content': 'Text'
}

Recipients 是用户 id 的数组,unRead 是尚未打开邮件的所有用户的数组。这按预期工作,但我需要查询所有消息的列表,以便它返回前 20 个结果,优先考虑未读的结果,例如:

db.messages.find({recipients: {$elemMatch: userID} })
  .sort({unRead: {$elemMatch: userID}})
  .limit(20)

但这不起作用。根据结果​​是否符合特定标准来确定结果优先级的最佳方法是什么?

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    如果您想按特定标准“加权”结果或在“排序”中使用任何类型的“计算值”,那么您需要使用 .aggregate() 方法。这允许在$sort 操作中使用“投影”值,对于这些值,只能使用文档中的当前字段:

    db.messages.aggregate([
        { "$match": { "messages": userId } },
        { "$project": {
            "recipients": 1,
            "unread": 1,
            "content": 1,
            "readYet": {
                "$setIsSubset": [ [userId], "$unread" ] }
            }
        }},
        { "$sort": { "readYet": -1 } },
        { "$limit": 20 }
    ])
    

    这里的$setIsSubset 运算符允许将“未读”数组与转换后的[userId] 数组进行比较,以查看是否有任何匹配项。结果将是true(其中 userId 存在)或false(不存在)。

    然后可以将其传递给$sort,它将优先于匹配项对结果进行排序(降序排序是true在顶部),最后$limit只返回指定数量的结果。

    因此,为了使用“排序”的计算术语,需要将值“投影”到文档中,以便对其进行排序。聚合框架就是您执行此操作的方式。

    另请注意,$elemMatch 不仅仅需要匹配数组中的单个值,您只需直接指定该值即可。它的目的是需要在单个数组元素上满足“多个”条件,这当然不适用于这里。

    【讨论】:

    • 这非常有效。谢谢!我要说的唯一评论是,在我将 $setIsSubSet 更改为 $setIsSubset 之前,Mongo 抛出了一个错误。
    • @beatniknight 典型的我。文档链接是正确的,但我的驼峰式大脑一直说它是两个单词并一直这样输入。
    • 最好使用$in 而不是$setIsSubset。所以:"$in": [ userId, "$unread" ]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    相关资源
    最近更新 更多