How to assign weights to searched documents in MongoDb? -


this might sounds simple question have spend on 3 hours achieve got stuck in mid way.

inputs:

  1. list of keywords
  2. list of tags

problem statement: need find documents database satisfy following conditions:

  1. list documents has 1 or many matching keywords. (achieved)
  2. list documents has 1 or many matching tags. (achieved)
  3. sort found documents on basis of weights: each keyword matching carry 2 points , each tag matching carry 1 point.

query: how can achieve requirement#3.

my attempt: in attempt able list on basis of keyword match (that without multiplying weight 2 ).

tags array of documents. structure of each tag like

{    "id" : "icc",    "some other key" : "some other value" } 

keywords array of string:

["women", "cricket"] 

query:

var predicate = [     {         "$match": {             "$or": [                 {                     "keywords" : {                         "$in" : ["cricket", "women"]                     }                 },                 {                     "tags.id" : {                         "$in" : ["icc"]                     }                 }             ]         }     },     {         "$project": {             "title":1,             "_id": 0,             "keywords": 1,             "weight" : {                 "$size": {                     "$setintersection" : [                         "$keywords" , ["cricket","women"]                     ]                 }             },             "tags.id": 1         }        },     {         "$sort": {             "weight": -1         }     } ];  

it seems close in attempt, of course need implement "match logic" in order final "score" value want.

it's matter of changing projection logic little, , assuming both "keywords" , "tags" arrays in documents:

db.collection.aggregate([     // match required documents     { "$match": {         "$or": [             {                 "keywords" : {                     "$in" : ["cricket", "women"]                 }             },             {                 "tags.id" : {                     "$in" : ["icc"]                 }             }         ]     }},      // inspect elements , create "weight"     { "$project": {         "title": 1,         "keywords": 1,         "tags": 1,         "weight": {             "$add": [                 { "$multiply": [                     {"$size": {                         "$setintersection": [                             "$keywords",                             [ "cricket", "women" ]                                      ]                     }}                 ,2] },                 { "$size": {                     "$setintersection": [                         { "$map": {                             "input": "$tags",                             "as": "t",                             "in": "$$t.id"                         }},                         ["icc"]                     ]                 }}             ]         }     }},      // sort "weight"     { "$sort": { "weight": -1 } } ]) 

so basicallt $map logic here "transforms" other array give id values comparison against "set" solution want.

the $add operator provides additional "weight" member want "weight" responses by.


Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

android - CollapsingToolbarLayout: position the ExpandedText programmatically -

Listeners to visualise results of load test in JMeter -