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