我有以下形式的文档集合:
{ _id: ObjectId(...)
, title: "foo"
, tags: ["bar", "baz", "qux"]
}
查询应该找到所有带有这些标签的文档。我目前使用这个查询:
{ "tags": { "$in": ["bar", "hello"] } }
而且它有效;返回所有标记为“bar”或“hello”的文档。
但是,我想按相关性排序,即匹配标签越多,文档在结果中出现的时间就越早。例如,标记为 ["bar", "hello", "baz"]
的文档在结果中应该高于标记为 ["bar", "baz", "boo"的文档"]
用于查询 ["bar", "hello"]
。我怎样才能做到这一点?
最佳答案
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 }
])
请注意,第一个和第三个管道成员看起来相同,这是有意和需要的。以下是这些步骤的作用:
- 只传递带有“bar”或“hello”标签的文档。
- 展开标签数组(意味着每个标签元素拆分为一个文档
- 只传递“bar”或“hello”标签(即丢弃其余标签)
- 按标题分组(也可以按“$_id”或原始文档的任何其他组合 加起来它有多少个标签(“bar”和“hello”)
- 按相关标签数量降序排列
- (可选)将返回的集合限制为前 10 个。
关于mongodb - 按与 MongoDB 的相关性排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12770673/