Mongodb:使用字段值查询,但也查询另一个未知的唯一字段

时间:2015-05-14 13:50:00

标签: mongodb geolocation database nosql

让我说我的文件是这种格式(随机数据):

{"_id" : 30, "lat": 36.1212111, "lon" : 120.2312112 "uuid" : 123123123}
{"_id" : 31, "lat": 36.1212111, "lon" : 120.2345112 "uuid" : 123123123}
{"_id" : 32, "lat": 36.1212111, "lon" : 120.2378112 "uuid" : 123123123}
{"_id" : 33, "lat": 36.1212111, "lon" : 120.2378112 "uuid" : 123123123}
{"_id" : 34, "lat": 36.1212111, "lon" : 120.2423112 "uuid" : 123123123}
{"_id" : 35, "lat": 36.1212111, "lon" : 120.2467112 "uuid" : 123123123}
{"_id" : 36, "lat": 36.1212111, "lon" : 127.2312112 "uuid" : 999999999}
{"_id" : 37, "lat": 36.1212111, "lon" : 127.9817112 "uuid" : 999999999}
{"_id" : 38, "lat": 36.1212111, "lon" : 128.2312112 "uuid" : 999999999}
{"_id" : 39, "lat": 36.1212111, "lon" : 128.8312112 "uuid" : 999999999}

让我们说这是车辆GPS数据的踪迹 我需要查询mongo。我只有开始和结束“lat”和“lon”值。例如,此处为uuid - 123123123,起始值为"lat": 36.1212111, "lon" : 120.2312112,结束值为"lat": 36.1212111, "lon" : 120.2467112。 但是,当我查询mongo时,我不想使用uuid。我想要文件的结果,属于同一个uuid。
简而言之,如果我有多辆车的位置跟踪数据,我需要查询一个独特的车辆的起点和终点,而不知道它的uuid。

2 个答案:

答案 0 :(得分:0)

不幸的是,我无法找到执行此操作的一步查询。所以我把它分成了几步。请注意以下几点:

  1. 我已经在我的json和查询中将_id字段更改为routeId。
  2. 代码不处理异步。所以在for循环中你需要处理它。 count(2)也在循环中硬编码。您需要将其替换为数组长度。
  3. 我在测试中添加了三个记录,以便可以测试多个uuid。

       {"routeId" : 60, "lat": 36.1212111, "lon" : 120.2312112, 
       "uuid" :44444123},
      {"routeId" : 61,"lat" : 36.8888111,"lon" : 120.9999112,
      "uuid" : 44444123},
        {"routeId" : 63,"lat" : 36.1212111,"lon" : 120.2467112,
      "uuid" : 44444123}
    
  4. 最后 - 这是代码。第一部分获得所有不同的uuid和它们各自的最小和最大routeId用​​于lat和lon匹配。 第二部分循环并检查min和max是否对应于正确的UUID,然后查询该UUID的所有数据。这样,如果提供的两个数据位于“中间” - 它们应该从最终结果中删除。

    var myArray = 
    db.stack_30229114.aggregate(
    {$match:{uuid : { $in:db.stack_30229114.distinct("uuid", {$or: [
    {lat:36.1212111,lon:120.2312112}, {lat:36.1212111,lon:120.2467112}]
    })}}},
    { $group: { _id: "$uuid", NrouteId: {$min:"$routeId"}, 
       XrouteId: {$max:"$routeId"}}}
    );
    for (i=0;i<2;i++){
      minResult = db.stack_30229114.find(
                            {routeId:myArray.result[i].NrouteId,
                            lat:36.1212111,lon:120.2312112}, {uuid:1}
                            );
        maxResult = db.stack_30229114.find(
                            {routeId:myArray.result[i].XrouteId,
                            lat:36.1212111,lon:120.2467112}, {uuid:1}
                            );
     if (minResult.uuid == maxResult.uuid){
            db.stack_30229114.find({uuid:minResult.uuid});
     }  
    }
    

答案 1 :(得分:0)

您要找的是aggregation framework。因此,要从数据中获得预期结果,您需要对其执行<input type="radio" />。这是您的数据的解决方案管道。假设您的收藏名称为aggregation pipeline

gps

以下是此示例聚合查询的结果:

db.gps.aggregate([
                    {$match: {
                                lat: {$gte: 36}, 
                                lon: {$gte: 120}, 
                                lat: {$lte: 37}, 
                                lon: {$lte: 130}
                             }
                    },
                    {$group: {_id: '$uuid', data: {$push: 
                                                           {
                                                               _id: '$_id', 
                                                               lat: '$lat', 
                                                               lon: '$lon'
                                                           }
                                                  }
                             }
                    }, 
                    {$project: 
                                {
                                   uuid: '$_id', 
                                   data: 1, 
                                   _id: 0
                                }
                    }
                 ])