gpt4 book ai didi

node.js - MongoDB 按相关性排序

转载 作者:可可西里 更新时间:2023-11-01 09:13:40 26 4
gpt4 key购买 nike

我正在尝试从 Node 上的 MongoDB 获取文档。假设文档具有以下结构:

{ "_id": ObjectId, "title" : String, "tags" : Array<String> }

我想按相关性对它们进行排序 - 因此,当我查找具有“蓝色”或“黄色”标签的文档时,我希望首先找到具有这两个标签的文档。到目前为止,我通过谷歌管理,反复试验:

var tags = [ "yellow", "blue" ];
db.collection('files').aggregate([
{ $project : { tags: 1 } },
{ $unwind : "$tags" },
{ $match : { "tags": { "$in": tags } } },
{ $group : { _id: "$_id", relevance: { $sum:1 } } },
{ $sort : { relevance : -1 } },
], function(err, success) {
console.log(success);
});

它工作得很好,我得到了 id 的排序集合:

[{"_id":"5371355045002fc820a09566","relevance":2},{"_id":"53712fc6c8fcd124216de6cd","relevance":2},{"_id":"5371302ebd4725dc1b908316","relevance":1}]

现在我将进行另一个查询并询问具有这些 ID 的文档 - 但这是我的问题:可以在一个查询中完成吗?

最佳答案

是的,当您实际根据 _id 进行分组时,您可以像往常一样,那么该值基本上等同于整个文档。所以这只是将整个文档存储在 _id 字段下的问题。

根据您的 MongoDB 版本,您可以采用多种方法,在 MongoDB 2.6 之前的版本中,您必须在初始 $project 中指定整个文档结构。在实际操作文档之前,管道中的阶段(可以选择在 $match 之后,这通常是个好主意):

var tags = ["yellow","blue"];
db.collection.aggregate([
{ "$project" : {
"_id": {
"_id": "$_id",
"title": "$title",
"tags": "$tags"
},
"tags": 1
}},
{ "$unwind": "$tags" },
{ "$match": { "tags": { "$in": tags } } },
{ "$group": { "_id": "$_id", "relevance": { "$sum":1 } } },
{ "$sort": { "relevance" : -1 } },
{ "$project": {
_id: "$_id._id",
"title": "$_id.title",
"tags": "$_id.tags"
}}
])

当然,在管道的末尾,您从 _id 字段中提取信息以取回您的原始结构。这是可选的,但您通常需要它。

对于 MongoDB 2.6 及更高版本,有一个变量可用于管道阶段,该变量保存管道该阶段的文档结构,称为 $$ROOT。 ,您可以像这样访问它作为上述表单的一种快捷方式:

var tags = ["yellow","blue"];
db.collection.aggregate([
{ "$project" : {
"_id": "$$ROOT",
"tags": 1
}},
{ "$unwind": "$tags" },
{ "$match": { "tags": { "$in": tags } } },
{ "$group": { "_id": "$_id", "relevance": { "$sum":1 } } },
{ "$sort": { "relevance" : -1 } },
{ "$project": {
"_id": "$_id._id",
"title": "$_id.title",
"tags": "$_id.tags"
}}
])

请记住,为了恢复文档,您仍然需要指定所有必填字段。

我会注意到,在这种情况下,正如前面提到的,当您使用匹配条件“过滤”文档时,您实际上应该使用 $match 进行过滤。在管道的“头部”声明。这是聚合框架唯一可以选择索引以优化查询的地方,它还减少了不符合您条件的文档的数量(假设不是所有的东西都有标签“黄色”或“蓝色”)通过剩余的流水线阶段:

db.collection.aggregate([
{ "$match": { "tags": { "$in": tags } } },
{ "$project" : {
"_id": {
"_id": "$_id",
"title": "$title",
"tags": "$tags"
},
"tags": 1
}},
{ "$unwind": "$tags" },
{ "$match": { "tags": { "$in": tags } } },
{ "$group": { "_id": "$_id", "relevance": { "$sum":1 } } },
{ "$sort": { "relevance" : -1 } },
{ "$project": {
_id: "$_id._id",
"title": "$_id.title",
"tags": "$_id.tags"
}}
])

无论如何,这通常比尝试执行另一个查询更有效,后者当然不会按照您所做的方式维护您的排序顺序。

关于node.js - MongoDB 按相关性排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23641752/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com