I am programing a Mongo query builder and I found two statements in documentation:
(Text search) The $match stage that includes a $text must be the first stage in the pipeline.
(Geo search) You can only use $geoNear as the first stage of a pipeline.
Which basically means the same, so... how to use those together?
I know this is an old question but I've recently had a similar problem so I thought I'd post my solution.
In my case I wanted:
I tackled it with a block of code like this:
let query = {}
if(req.query.keywords){
  if(req.query.lng || req.query.lat){
    db.collection("service")
      .find({ $text: { $search: req.query.keywords }})
      .toArray()
      .then(docs => query._id = { $in: docs.map(doc => doc._id) })
  } else {
    query.$text = { $search: req.query.keywords }
  }
}
if(req.query.lat && req.query.lng){
  query.location = {
    $nearSphere: {
      $geometry: {
        type: "Point",
        coordinates: [req.query.lng, req.query.lat]
      }
    }
  }
}
db.collection("service").find(query)
Basically if a text search or a geo search is desired by itself, the appropriate query is built no problem. If both are needed, it does a text query first, and then passes the returned document ids as a filter to the second.
This is the most performant solution I could find!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With