按与MongoDB的相关性排序

qox*_*qox 5 sorting mongodb

我有以下表格的文件集:

{ _id: ObjectId(...)
, title: "foo"
, tags: ["bar", "baz", "qux"] 
}
Run Code Online (Sandbox Code Playgroud)

查询应查找包含任何这些标记的所有文档.我目前使用此查询:

{ "tags": { "$in": ["bar", "hello"] } }
Run Code Online (Sandbox Code Playgroud)

它有效; 所有标记为"bar"或"hello"的文档都将被退回.

但是,我想按相关性排序,即文档在结果中出现的越早,匹配标记越多.例如,标记的文档["bar", "hello", "baz"]在结果中应该高于["bar", "baz", "boo"]为查询标记的文档["bar", "hello"].我怎样才能做到这一点?

Asy*_*sky 10

MapReduce和客户端做得太慢 - 你应该使用聚合框架(MongoDB 2.2中的新增功能).

它可能看起来像这样:

db.collection.aggregate([
   { $match : { "tags": { "$in": ["bar", "hello"] } } },
   { $unwind : "$tags" },
   { $match : { "tags": { "$in": ["bar", "hello"] } } },
   { $group : { _id: "$title", numRelTags: { $sum:1 } } },
   { $sort : { numRelTags : -1 } }
   //  optionally
   , { $limit : 10 }
])
Run Code Online (Sandbox Code Playgroud)

请注意,第一个和第三个管道成员看起来相同,这是有意和需要的.以下是步骤:

  1. 仅传递标记为"bar"或"hello"的文档.
  2. 展开标签数组(意味着每个标签元素拆分为一个文档)
  3. 仅传递标签"bar"或"hello"(即丢弃其余标签)
  4. 按标题分组(也可以通过"$ _id"或原始文档的任何其他组合来累加它有多少标签("bar"和"hello")
  5. 按相关标签的数量降序排序
  6. (可选)将返回的集合限制为前10.