MongoDB: get documents by tags

2019-01-23 07:15发布

问题:

I've got documents containing tags array. I want to provide tags based recommendations on site, so I need to get documents containing same tags + documents that don't match 1 tag + documents that don't match 2 tags and etc...

How do I do that?

回答1:

example collection:

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

find all that include the tag "blue"

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

find all tagged "blue" and only blue

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

find all tagged "blue" and "cheap"

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

find all not "blue"

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

find all "blue" and "cheap" but not "red" and not "tall"

not possible in my mongo db. From mongodb 1.9.1 on something like this should work, though (not tested):

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


回答2:

The rephrased question is:

Suppose if job postings have search tags attached like

Job Postings

[{_id : ObjectId(1249999493),tags : ['Location1', 'SkillSet1', 'SkillSet2', 'Someother1', 'Someother2']},
 {_id : ObjectId(1249999494),tags : ['Location3', 'SkillSet1', 'SkillSet0', 'Someother4', 'Someother3']}]

Now, he wants the records having tags ['Location1','SkillSet1', 'SkillSet0']

And the selected docs having more keywords from the query should come first. Less keywords matching should come last. So, that one can get more suitable job posting for the search query.

Am I sensible or do I need to re-phrase ?



回答3:

Steps:

  1. Find matching products which contains any of the specified keys.

  2. Unfold on keys

  3. Do find again to filter unwanted after unfolding

  4. Group them by adding key occurrence

  5. Sort desc to get most relevant first

[{ "$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}]



标签: mongodb tags