如何与geoNear一起执行文本搜索



我正在编写一个Mongo查询生成器,我在文档中发现了两个语句:

(文本搜索)包含$ Text的$match阶段必须是管道中的第一阶段。

(地理搜索)你只能使用$geoNear作为管道的第一阶段。

意思是一样的,所以…如何一起使用它们?

我知道这是一个老问题,但我最近有一个类似的问题,所以我想我应该张贴我的解决方案。

在我的例子中,我想:

  • 首先在用户提供的关键字上使用全文搜索作为过滤器
  • 然后,根据与用户提供的坐标的距离对结果进行排序
  • 用户可以选择提供关键词、位置或两者都提供(困难的情况)

我用这样一段代码来处理它:


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)

基本上,如果文本搜索或地理搜索本身需要,则构建适当的查询没有问题。如果两者都需要,则首先执行文本查询,然后将返回的文档id作为过滤器传递给第二个。

这是我能找到的性能最好的解决方案!

我认为你做不到。我过去做过的一件事是执行查询并将结果合并到应用程序代码中。

您可以创建一个$match聚合阶段,并使用$geoWithin(或$geoIntersect)和$text操作符。那似乎是最好的解决办法。

MongoDB Atlas Search还允许同时过滤全文和位置

最新更新