MongoDB:按标签获取文档

19

我有一些包含tags数组的文档。我想在网站上提供基于标签的推荐,所以我需要获取包含相同标签的文档+不匹配1个标签的文档+不匹配2个标签等等...

我该如何做到这一点?


3
根据您在下面所说的内容,这个问题不太清楚。也许提供一个期望输出的示例会有所帮助。 - Matthew Nichols
3个回答

29

示例集合:

db.tags.insert({"tags":["red", "tall", "cheap"]});
db.tags.insert({"tags":["blue", "tall", "expensive"]});
db.tags.insert({"tags":["blue", "little", "cheap"]}); 

找出所有包含标签"blue"的内容

db.tags.find({tags: { $elemMatch: { $eq: "blue" } }})

查找所有标记为“blue”的内容,且只包含蓝色的。

db.tags.find({tags: "blue"})

查找所有被标记为“蓝色”和“便宜”的项目

db.tags.find({ tags: { $all: ["cheap", "blue"] } } )

查找所有非“蓝色”的

db.tags.find({tags: { $ne: "blue" } })

查找所有“蓝色”和“便宜”的但不包括“红色”和“高个子”的内容。

在我的MongoDB中无法实现。从MongoDB 1.9.1开始,应该可以像这样工作(未经测试):

db.tags.find({ $and: [ {tags: { $all: ["blue", "cheap"] } }, { tags: { $nin: ["red", "tall"] } } ] })

6
你没有理解我的意思。我不需要完全匹配。我想要包含至少一个标签的所有文档,按照它所包含的原始标签数量排序。 - Daniel
1
你能否更精确地阐述问题? - rompetroll
1
使用$in操作符查找一些但不是全部,这个答案让我误以为$all的行为类似于$in。https://docs.mongodb.org/v3.0/reference/operator/query/in/#op._S_in - nak

1
重新表述的问题是:
假设工作职位发布上有附加搜索标签,如下所示:
工作职位发布
[{_id : ObjectId(1249999493),tags : ['Location1', 'SkillSet1', 'SkillSet2', 'Someother1', 'Someother2']},
 {_id : ObjectId(1249999494),tags : ['Location3', 'SkillSet1', 'SkillSet0', 'Someother4', 'Someother3']}]

现在,他想要具有标签['Location1','SkillSet1','SkillSet0']的记录。选择的文档应该优先考虑查询关键字的数量更多。匹配较少的关键字应该排在最后。这样,用户可以获得更适合搜索查询的工作岗位。请问我的表述是否清晰?

在我看来,那看起来是正确的。似乎这个“四年前的问题”更多地涉及到过滤结果而不是创建搜索参数。 - monsto
@nilsi 是的,这不是一个答案,但我试图通过一个场景来解释问题。 - Kishore Relangi

0

步骤:

  1. 查找包含任何指定关键字的匹配产品。

  2. 在关键字上展开

  3. 再次查找以过滤展开后不需要的内容

  4. 通过添加关键字出现次数对它们进行分组

  5. 按降序排序以获取最相关的结果

[{ "$match" : { "keys" : { "$in" : [ { "$regex" : "text" , "$options" : "i"}]}}}, { "$unwind" : "$keys"}, { "$match" : { "keys" : { "$in" : [ { "$regex" : "text" , "$options" : "i"}]}}}, { "$group" : { "_id" : { "productId" : "$productId"} , "relatedTags" : { "$sum" : 1} }}, { "$sort" : { "relatedTags" : -1}},{ "$limit" : 10}]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接