Zainul Abideen
Zainul Abideen

Reputation: 1900

recursively search a string in multiple collections against all fields

I want to recursively/deeply search a string in all fields of multiple collections. As a first step to perform deep search I aggregated all data from multiple collections using the $lookup aggregate function.

Here's an example of what I tried so far:

Let's say we have 3 collections

collection1: users

{ 
 "_id" : ObjectId(bcd13), 
 "email" : "[email protected]", 
 "name": "abc", 
 "password": "abc.90" 
}
{ 
 "_id" : ObjectId(abc1234), 
 "email" : "[email protected]", 
 "name": "xyz", 
 "password": "xyz_.123" 
}

collection2: skills

{ 
 "_id" : ObjectId(ghj78), 
 "user_id" : "bcd13", 
 "skills": ["React", "PHP", ".Net"] 
}

collection3: experiences

{ 
 "_id" : ObjectId(tyu67), 
 "user_id" : "bcd13", 
 "experiences": [
  {"organization": "Microsoft", "from": "2020-03-10", "to":"present"}, 
  {"organization": "Meta", "from": "2018-01-20", "to":"2020-03-10"}
 ] 
}

To perform deep search first of all I aggregated the above data using below aggregation pipelines:

db.users.aggregate([
  {
    $addFields: {
      user_id_string: {
        $toString: "$_id",
      },
    },
  },
  {
    $lookup: {
      from: "skills",
      localField: "user_id_string",
      foreignField: "user_id",
      as: "skills",
    },
  },
  {
    $unwind: {
      path: "$skills",
      preserveNullAndEmptyArrays: true,
    },
  },
  {
    $lookup: {
      from: "experiences",
      localField: "user_id_string",
      foreignField: "user_id",
      as: "experience",
    },
  },
  {
    $unwind: {
      path: "$experience",
      preserveNullAndEmptyArrays: true,
    },
  },
])

The result of above aggregation pipelines looks as follows:

[{ 
 "_id" : ObjectId(bcd13), 
 "email" : "[email protected]", 
 "name": "abc", 
 "password": "abc.90" 
 "skills": { 
     "_id" : ObjectId(ghj78), 
     "user_id" : "bcd13", 
     "skills": ["React", "PHP", ".Net"] 
    }
 "experience": { 
     "_id" : ObjectId(tyu67), 
     "user_id" : "bcd13", 
     "experiences": [
      {"organization": "Microsoft", "from": "2020-03-10", "to":"present"}, 
      {"organization": "Meta", "from": "2018-01-20", "to":"2020-03-10"}
     ] 
    }
}
{ 
 "_id" : ObjectId(abc1234), 
 "email" : "[email protected]", 
 "name": "xyz", 
 "password": "xyz_.123" 
}]

Once we get the aggregated data from multiple collections now I want to perform a deep search in this aggregated data against a single string.

My search strings could looks like this:

React developer with 2 years of experience.
dot net developer in California.

...etc

So with these search strings I should be able to perform deep search in aggregated data against all fields with the keywords in search strings. I tried many ways like $redact, $graphLookup, $match but nothing solved the problem and now I am overwhelmed with the information. Can anyone help me with the next aggregate pipeline that I should use next and how to use that?

Thanks in advance.

Upvotes: 3

Views: 175

Answers (1)

Greg
Greg

Reputation: 11

The "skill" and "experience" collection contain user_id, which means they belongs to the user. The best practice in MongoDB is to save them together as one collection instead of 3 collections.

After you put them together, you can choose whether using legacy Text Search on multi fields or directly using Atlas Search.

Regards

Upvotes: 1

Related Questions