Mongo 按计算条件排序 [英] Mongo sort on a calculated condition

查看:29
本文介绍了Mongo 按计算条件排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Mongo collection of messages that looks like this:

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

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

Recipients is an array of user ids, and unRead is an array of all users who have not yet opened the message. That's working as intended, but I need to query the list of all messages so that it returns the first 20 results, prioritizing the unread ones first, something like:

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

但这行不通.根据结果​​是否符合特定标准对结果进行优先排序的最佳方法是什么?

But that doesn't work. What's the best way to prioritize results based on whether they fit a certain criteria?

推荐答案

如果您想按特定标准对结果进行加权"或在排序"中有任何类型的计算值",那么您需要 .aggregate() 方法代替.这允许在 $sort 操作,只能使用文档中的一个present字段:

If you want to "weight" results by certain criteria or have any kind of "calculated value" within a "sort", then you need the .aggregate() method instead. This allows "projected" values to be used in the $sort operation, for which only a present field in the document can be used:

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 在它不存在的地方.

Here the $setIsSubset operator allows comparison of the "unread" array with a converted array of [userId] to see if there are any matches. The result will either be true where the userId exists or false where it does not.

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

This can then be passed to $sort, which orders the results with preference to the matches ( decending sort is true on top ), and finally $limit just returns the results up to the amount specified.

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

So in order to use a calulated term for "sort", the value needs to be "projected" into the document so it can be sorted upon. The aggregation framework is how you do this.

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

Also note that $elemMatch is not required just to match a single value within an array, and you need only specify the value directly. It's purpose is where "multiple" conditions need to be met on a single array element, which of course does not apply here.

这篇关于Mongo 按计算条件排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆