2013-06-02 60 views
12

我想知道是否可以结合文本搜索和对结果运行地理空间查询/我该怎么做。此刻我正在使用Mongoose,但不介意使用直接Mongo来执行命令。MongoDB:结合文本搜索和地理空间查询

我想要做的是允许用户搜索产品并返回特定位置内的结果。我有两个命令分开运行,但无法弄清楚如何组合它们。

回答

3

您可以通过添加一个滤波器参数(我使用node-mongodb-native)过滤文本搜索:

db.command({ text: 'thecollection', search: searchString, filter: query }, function(err, o) { 

    if (err) throw err; 

    var results = o.results.map(function(result) { return result.obj }); 

    // process the response ... 

    }); 

如果你想要做一个粗略的地理搜索,您可以通过定义筛选结果最小值和最大值周围的经纬度:

var distances = {'200m': 0.002, '500m': 0.005, '1km': 0.01, '5km': 0.05 } 

    , distance = distances[reqDis]; 


var query = { 
    latitude: { $lt: reqLat+distance, $gt: reqLat-distance }, 
    longitude: { $lt: reqLng+distance, $gt: reqLng-distance } 
}; 

// put the query in the db.command as described above 

这里是MongoDB的文档中的主题的东西:http://docs.mongodb.org/manual/tutorial/limit-number-of-items-scanned-for-text-search/

+1

我可以使用$ lt和$ GT运营商如果经度和纬度都存储在一个数组;类似于 - loc:[50.433234,20,220123] –

4

Mongo DB本身不支持同时进行文本和地理搜索。 按照

  1. 尝试regex文字和附近的空间搜索[参考这个(http://docs.mongodb.org/manual/reference/limits/#Queries-cannot-use-both-text-and-Geospatial-Indexes

    你可以做到这一点。

    var aggregate=YourCollection.aggregation() 
    aggregate.near({ 
        near:coord, 
        includeLocs: "loc", 
        distanceField: "distance", 
        maxDistance: distance 
    }); 
    aggregate.match({name:{$regex:keyword,$options: 'i'}}) 
    aggregate.exec(function(err,yourDocuments){ 
        //your smart code 
    }) 
    
  2. 使用搜索文本索引并使用以下查询查找最近的文档,它与之前所说的相反。

    var aggregate=YourCollection.aggregate(); 
    var match= { 
        latitude: { $lt: yourCurrentLatitude+maxDistance, $gt: yourCurrentLatitude-maxDistance }, 
        longitude: { $lt: yourCurrentLongitude+maxDistance, $gt: yourCurrentLongitude-maxDistance }, 
        {$text:{$search:keyword}} 
    }; 
    
    
    aggregate.match(match).exec(function(err,yourDocuments){//your smart code}) 
    

` 3.分手了的文档转换成使用MapReduce的部分。通过文本/地理搜索过滤搜索结果并将其存储到新的集合中。浏览新的收藏集,并通过过滤器找到确切的收藏。

YourCollection.mapReduce(map, reduce, {out: {inline:1, query : yourFirstQuery}}, function(err, yourNewCollection) { 
    // Mapreduce returns the temporary collection with the results 
     collection.find(yourNewQuery, function(err, result) { 
      //your awsome code 
     }); 
    }); 
4

这是一个非常普遍的需求,在一个用例中需要进行地理过滤器和文本搜索,但不幸的是,这个用例并没有被mongodb直接支持。

下面的代码使用mongoose驱动程序,首先根据位置(经度和纬度)过滤文件,然后根据搜索到的术语进一步过滤。

var area = { 
    center: [51, -114], //lng = 51 and lat = -114 
    radius: 100, 
    unique: true //this option is deprecated from MongoDB 2.6 on as mongodb no longer returns duplicate results 
}; 

var query = Post.where('loc').within().circle(area) //Step 1: filter based on location 
    //Step 2: Next filter on the basis of searched text 
    .where({ 
     $text: { 
      $search: <searchTerm> 
     } 
    }, { 
     score: { 
      $meta: 'textScore' 
     } 
    }) 
    //Step 3: Filter any document fields that should not be returned in the result 
    .select({ 
     "val1": 0, 
     "val2": 0 
    }); 

//Execute the query 
query.exec(function (err, result) { 
    if (err) { 
     //return error in the response 
    } 
    //return result object in the response 
}); 

在此代码“邮报”是猫鼬的模式类似下面

var PostSchema = new Schema({ 
    title: String, 
    description: String, 
    loc: { 
     type: [Number], // [<longitude>, <latitude>] 
     index: '2d' // create the geospatial index 
    } 
    //some other fields 
} 

module.exports = mongoose.model('Post', PostSchema); 

也为搜索区域,有可用的样箱

var lowerLeft = [40.73083, -73.99756] 
var upperRight= [40.741404, -73.988135] 
query.where('loc').within().box(lowerLeft, upperRight) 

其他选项对于这两个地理位置搜索和文本搜索工作,请确保在loc字段和文本字段上有索引。更多细节在这里。 loc Searchtext search

0

使用地理空间可以进行全文搜索。

可以在蒙戈外壳试试这个:

db.collection.aggregate([ 
    { "$geoNear": { 
     "near": { 
      "type": "Point", 
      "coordinates": [ 
       -73.86, 
       41.076 
      ] 
     }, 
     "spherical": true, 
     "maxDistance": 600, 
     "distanceField": "distance", 
     "query": { 
      "fieldname": /querystring/ 
     } 
    }} 
]) 

使用全文搜索:

db.collection.find({ 
    "$text": { "$search": "query string" }, 
    "location": { // this will your field name 
     "$geoWithin": { 
      "$centerSphere": [[ 
       -73.86, 
       43.03 
      ], 500 ] 
     } 
    } 
}) 
相关问题