Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB:结合文本搜索和地理空间查询_Mongodb_Mongoose - Fatal编程技术网

MongoDB:结合文本搜索和地理空间查询

MongoDB:结合文本搜索和地理空间查询,mongodb,mongoose,Mongodb,Mongoose,我想知道是否有可能结合文本搜索和对结果运行地理空间查询/我将如何做。我现在正在使用Mongoose,但不介意直接使用Mongo来执行命令 我试图做的是允许用户搜索产品并返回特定位置内的结果。我有两个单独运行的命令,但不知道如何组合它们。您可以通过添加筛选参数筛选文本搜索(我正在使用): 如果您想进行粗略的地理搜索,可以通过在经纬度周围定义最小值和最大值来过滤结果: var distances = {'200m': 0.002, '500m': 0.005, '1km': 0.01, '5km':

我想知道是否有可能结合文本搜索和对结果运行地理空间查询/我将如何做。我现在正在使用Mongoose,但不介意直接使用Mongo来执行命令


我试图做的是允许用户搜索产品并返回特定位置内的结果。我有两个单独运行的命令,但不知道如何组合它们。

您可以通过添加筛选参数筛选文本搜索(我正在使用):

如果您想进行粗略的地理搜索,可以通过在经纬度周围定义最小值和最大值来过滤结果:

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