Reputation: 893
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?
Upvotes: 6
Views: 1158
Reputation: 248
You can create a $match aggregation stage and use $geoWithin (or $geoIntersect) along with $text operator. That seems to be the best solution.
MongoDB Atlas Search also allows filtering for full-text and location at the same time.
Upvotes: 0
Reputation: 318
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!
Upvotes: 3
Reputation: 169
I don't think you can. One thing I've done in the past is perform both queries and merge the results in the application code.
Upvotes: 1