2013-06-02 36 views
12

Tôi đã tự hỏi liệu có thể kết hợp tìm kiếm văn bản và chạy truy vấn không gian địa lý trên các kết quả/cách tôi thực hiện nó hay không. Tôi đang sử dụng Mongoose vào lúc này nhưng đừng bận tâm sử dụng Mongo thẳng cho các lệnh.MongoDB: Kết hợp tìm kiếm văn bản và truy vấn không gian địa lý

Điều tôi đang cố gắng làm là cho phép người dùng tìm kiếm sản phẩm và trả về kết quả nằm trong một vị trí cụ thể. Tôi có hai lệnh chạy riêng, nhưng không thể tìm ra cách kết hợp chúng.

Trả lời

3

Bạn có thể lọc tìm kiếm văn bản bằng cách thêm một tham số bộ lọc (Tôi đang sử dụng 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 ... 

    }); 

Nếu nó là một tìm kiếm địa lý thô bạn muốn làm, bạn có thể lọc kết quả của bạn bằng cách định nghĩa một min và max khoảng vĩ độ kinh độ của bạn:

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 

Dưới đây là một cái gì đó về chủ đề trong tài liệu MongoDB: http://docs.mongodb.org/manual/tutorial/limit-number-of-items-scanned-for-text-search/

+1

tôi có thể sử dụng $ lt và $ gt khai thác nếu vĩ độ và kinh độ được lưu trữ trong một mảng ; một cái gì đó như- loc: [50.433234,20,220123] –

4

Mongo DB chính nó không hỗ trợ văn bản và tìm kiếm địa lý cùng một lúc. [Tham khảo này] (http://docs.mongodb.org/manual/reference/limits/#Queries-cannot-use-both-text-and-Geospatial-Indexes)

Bạn có thể làm điều đó bằng cách làm theo

  1. Hãy thử regex cho văn bản và gần cho tìm kiếm không gian.

    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. sử dụng tìm kiếm chỉ mục văn bản và sử dụng truy vấn sau đây cho các tài liệu gần nhất, nó trái ngược với những gì đã nói trước đây.

    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. Phân ra các tài liệu thành nhiều phần bằng MapReduce. Lọc các doucmets bằng văn bản/tìm kiếm địa lý và lưu nó vào một bộ sưu tập mới. Đi qua bộ sưu tập mới và tìm bộ sưu tập chính xác bằng bộ lọc stillig.

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

Đây là yêu cầu rất phổ biến trong trường hợp sử dụng bộ lọc địa lý và tìm kiếm văn bản trong một trường hợp sử dụng không may được hỗ trợ trực tiếp bởi mongodb.

Mã dưới đây sử dụng trình điều khiển mongoose, lọc tài liệu đầu tiên dựa trên vị trí (kinh độ và vĩ độ) và sau đó thêm bộ lọc dựa trên cụm từ tìm kiếm.

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 
}); 

Trong mã này "Post" là một cái gì đó giản đồ cầy mangut như dưới đây

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); 

Ngoài ra cho khu vực tìm kiếm, có những lựa chọn khác có sẵn như hộp

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

Đối với cả Định vị tìm kiếm và tìm kiếm văn bản để hoạt động, đảm bảo có chỉ mục trên trường địa phương và trường văn bản. Thêm chi tiết ở đây. loc Searchtext search

0

Tìm kiếm toàn văn bản có thể với không gian địa lý.

Bạn có thể thử điều này trong vỏ Mongo:

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

Sử dụng tìm kiếm văn bản đầy đủ:

db.collection.find({ 
    "$text": { "$search": "query string" }, 
    "location": { // this will your field name 
     "$geoWithin": { 
      "$centerSphere": [[ 
       -73.86, 
       43.03 
      ], 500 ] 
     } 
    } 
}) 
Các vấn đề liên quan