【问题标题】:mongoose $gte and $lte not working properly猫鼬 $gte 和 $lte 无法正常工作
【发布时间】:2019-07-07 01:10:29
【问题描述】:

最近我一直在开发一个应用程序,我需要在其中获取基于特定位置的半径内的文档。当我将纬度和经度发送到服务器时,我的代码会正确计算最小和最大纬度和经度。我尝试将计算出的数字放入 mongoose 查询中的 $gte 和 $lte 中,但预期的结果不会出现!

我尝试了以下猫鼬查询:

{ name: /^انار0$/i }

我收到了以下回复:

[
{
    "rating": {
        "average": 0,
        "count": 0
    },
    "location": {
        "latitude": 33.635,
        "longitude": 70.889
    },
    "status": "ONLINE",
    "_id": "5c62fa691fab8f24209f36e6",
    "name": "انار0",
    "_type": "CAFE"
}
]

但是当我发送位置并且查询变成以下内容时:

{ location:
    { latitude:
        { 
            '$gte': 33.626016646154675,
            '$lte': 33.64398335384532
         },
     longitude:
         { 
             '$gte': 70.88152061196703,
             '$lte': 70.89647938803296
          } 
      },
      name: /^انار0$/i
}

我得到一个空的 jsonarray 作为我的响应,其中响应不应与前一个查询不同!

这是我的代码:

let query = {};
if (location.lat && location.lng){
    /**
     * earth radius is approximately 6378 kilometers
     * so each degree is 111.3170 km based on the (2*Pi/360) * 6378
     * basically each degree is 111317 meters
     * if we want shops in a 1000 meter radius then 1000 meters in degree would be 1000 / 111317
     */
    let Pi = Math.PI;
    if (isNaN(radius)) {
        radius = 1000; // radius in meters
    }
    let radiusInDegrees = radius / 111317;

    let locationQuery = {};
    locationQuery.latitude = {};
    locationQuery.longitude = {};

    locationQuery.longitude.$gte = location.lng - (radiusInDegrees * Math.cos(location.lat * (Pi/180)));
    locationQuery.longitude.$lte = location.lng + (radiusInDegrees * Math.cos(location.lat * (Pi/180)));

    locationQuery.latitude.$gte = location.lat - radiusInDegrees;
    locationQuery.latitude.$lte = location.lat + radiusInDegrees;

    query.location = locationQuery;
}
if (s !== undefined){
    query.name = new RegExp(`^${s}$`, "i");
}
database.Shop.find(query)
    .sort(sort)
    .limit(per_page)
    .skip((page - 1) * per_page)
    .select("name logo status rating _type location")
    .populate("logo")
    .exec((err, shops) => {
        if (err){
            res.status(500);
            return res.json({
                status_code: 500,
                message: "internal server error"
            });
        }
        database.Shop.count(query, (err, count) => {
            res.header("document-count", count);
            let max_pages = Math.ceil(count / per_page);
            res.header("total-pages", max_pages);
            let fullUrl = req.protocol + '://' + req.get('host') + req.baseUrl;
            let originalQS = req.query;
            originalQS.page = page;
            originalQS.per_page = per_page;
            if (page < max_pages) {
                let qs = originalQS;
                qs.page = page + 1;
                res.header("next-page", fullUrl + "?" + queryString.stringify(qs));
            }
            if (page > 1 && max_pages > 0) {
                let previous_page = page - 1;
                if (page > max_pages) {
                    previous_page = max_pages;
                }
                let qs = originalQS;
                qs.page = previous_page;
                res.header("previous-page", fullUrl + "?" + queryString.stringify(qs));
            }
            res.header("page", page);
            res.json(shops);
        });
    });

【问题讨论】:

    标签: node.js mongodb mongoose ecmascript-6


    【解决方案1】:

    您必须更新查询格式。对于嵌套对象,您需要使用点 (.) 表示法。所以使用 "location.longitude" 而不是 { location:{ latitude:{....

    因此您可以更新代码以构建如下查询

    let query = {};
    if (location.lat && location.lng) {
        let Pi = Math.PI;
        if (isNaN(radius)) {
            radius = 1000; // radius in meters
        }
        let radiusInDegrees = radius / 111317;
    
    
        query["location.longitude"] = {
            $gte: location.lng - (radiusInDegrees * Math.cos(location.lat * (Pi / 180))),
            $lte: location.lng + (radiusInDegrees * Math.cos(location.lat * (Pi / 180)))
        };
    
        query["location.latitude"] = {
            $gte: location.lat - radiusInDegrees,
            $lte: location.lat + radiusInDegrees
        };
    }
    if (s !== undefined) {
        query.name = new RegExp(`^${s}$`, "i");
    }
    

    这将生成像下面这样的查询并且应该可以工作

    {
        'location.latitude': { '$gte': 33.626016646154675, '$lte': 33.64398335384532 },
        'location.longitude': { '$gte': 70.88152061196703, '$lte': 70.89647938803296 },
        name: /^انار0$/i
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-17
      • 2018-06-18
      • 2019-11-10
      • 1970-01-01
      • 2017-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多