Mongo根据计算的条件进行sorting

我有一个Mongo集合的消息,看起来像这样:

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

收件人是用户ID的数组,而unRead是尚未打开邮件的所有用户的数组。 这是按预期工作的,但我需要查询所有消息的列表,以便返回前20个结果,首先优先处理未读的消息,如下所示:

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

但是这不起作用。 根据是否符合某个标准,对结果进行优先sorting的最佳方法是什么?

如果你想通过一定的标准来“加权”结果或者在“sorting”中有任何种类的“计算值”,那么你需要改变.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]的转换数组,以查看是否有任何匹配。 如果userId存在,结果将是true ,否则返回false

然后可以将它传递给$sort ,它将结果优先匹配到匹配(上面的sorting是true ),最后$limit只是将结果返回到指定的数量。

因此,为了使用一个被称为“sorting”的术语,该值需要被“投影”到文档中,以便可以对其进行sorting。 聚合框架是你如何做到这一点。

还要注意$elemMatch不是只需要匹配数组中的一个值,而只需要直接指定值。 目的是在单个数组元素上需要满足“多个”条件,这当然不适用于此。