Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

167
Views
MongoDb score results based on simple matches

I'm trying to create a simple search algorithm that will try to match against a first name, last name, and/or set of tags, as an example:

[
  {
    "key": 1,
    "fname": "Bob",
    "lname": "Smith",
    "tags": [
      "a",
      "b",
      "c"
    ]
  },
  {
    "key": 2,
    "fname": "John",
    "lname": "Jacob",
    "tags": [
      "c",
      "d",
      "e"
    ]
  },
  {
    "key": 3,
    "fname": "Will",
    "lname": "Smith",
    "tags": [
      "a",
      "b",
      "c"
    ]
  }
]

This works with the following, but I can only get the tags count. Basically what I'm going for here is to match first-name, last-name, or tags and for each match store a "point":

db.collection.aggregate([
  {
    $match: {
      $or: [
        {
          "fname": "Will"
        },
        {
          "lname": "Smith"
        },
        {
          tags: {
            $in: [
              "b",
              "c"
            ]
          }
        }
      ]
    }
  },
  {
    $project: {
      tagsMatchCount: {
        $size: {
          "$setIntersection": [
            [
              "b",
              "c"
            ],
            "$tags"
          ]
        }
      }
    }
  },
  {
    "$sort": {
      tagsMatchCount: -1
    }
  }
])

Here's the sandbox I'm playing with: https://mongoplayground.net/p/DFJQZY-dfb5

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Query

  • create a document to hold the matches each in separate field
  • add one extra field total
  • keep only those with at least 1 match
  • you can sort also after by any of the 3 types of matches or by total, like
    {"$sort":{"points.total":-1}}
  • if you have index that can be used, remove my $match and add your match as first stage like in your example

Test code here

aggregate(
[{"$set":
  {"points":
   {"fname":{"$cond":[{"$eq":["$fname", "Will"]}, 1, 0]},
    "lname":{"$cond":[{"$eq":["$lname", "Smith"]}, 1, 0]},
    "tags":{"$size":{"$setIntersection":["$tags", ["b", "c"]]}}}}},
 {"$set":
  {"points.total":
   {"$add":["$points.fname", "$points.lname", "$points.tags"]}}},
 {"$match":{"$expr":{"$gt":["$points.total", 0]}}}])
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!