MongoDB:结合文本搜索和地理空间查询
我想知道是否有可能结合文本搜索和对结果运行地理空间查询/我将如何做。我现在正在使用Mongoose,但不介意直接使用Mongo来执行命令MongoDB:结合文本搜索和地理空间查询,mongodb,mongoose,Mongodb,Mongoose,我想知道是否有可能结合文本搜索和对结果运行地理空间查询/我将如何做。我现在正在使用Mongoose,但不介意直接使用Mongo来执行命令 我试图做的是允许用户搜索产品并返回特定位置内的结果。我有两个单独运行的命令,但不知道如何组合它们。您可以通过添加筛选参数筛选文本搜索(我正在使用): 如果您想进行粗略的地理搜索,可以通过在经纬度周围定义最小值和最大值来过滤结果: var distances = {'200m': 0.002, '500m': 0.005, '1km': 0.01, '5km':
我试图做的是允许用户搜索产品并返回特定位置内的结果。我有两个单独运行的命令,但不知道如何组合它们。您可以通过添加筛选参数筛选文本搜索(我正在使用): 如果您想进行粗略的地理搜索,可以通过在经纬度周围定义最小值和最大值来过滤结果:
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文档中有一些关于这个主题的内容:mongodb本身不支持同时进行文本和地理搜索。 但是您可以组合查询并获得结果 解决
这是一个非常常见的需求,在一个用例中需要地理过滤器和文本搜索,不幸的是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
});
要使地理位置搜索和文本搜索都起作用,请确保在loc字段和文本字段上有索引。这里有更多细节。而且使用地理空间数据库可以进行全文搜索 您可以在mongo shell中尝试以下操作:
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 ]
}
}
})
如果纬度和经度存储在数组中,是否可以使用$lt和$gt运算符;类似于-loc[50.433234,20220123]
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
});
});
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)
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 ]
}
}
})