【问题标题】:Mongodb: Query with a field value, but also another unknown unique fieldMongodb:使用字段值进行查询,但也是另一个未知的唯一字段
【发布时间】:2015-05-14 13:50:00
【问题描述】:

假设我的文档是这种格式(随机数据):

{"_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。我只有开始和结束“纬度”和“经度”值。例如,这里对于 uuid -123123123,起始值为 "lat": 36.1212111, "lon" : 120.2312112,结束值为 "lat": 36.1212111, "lon" : 120.2467112。 但是,当我查询 mongo 时,我不想使用 uuid。我想要的结果文件,属于同一个uuid。
简而言之,如果我有多个车辆的位置轨迹数据,我需要在不知道其 uuid 的情况下查询唯一车辆的起点和终点。

【问题讨论】:

  • 如果有两辆(或更多)车辆起点和终点相同但路线不同怎么办?
  • 两者兼得。为简单起见,我们首先假设不存在这种情况。
  • 让我们澄清一下,如果您以这种方式查询 mongo - 开始:"lat": 35, "lon" : 119,结束:"lat": 37, "lon" : 121,那么您期望什么结果?
  • @n9code:我期待一个属于同一 UUID 的文档数组。
  • @spiralarchitect 对你有用吗?

标签: mongodb geolocation database nosql


【解决方案1】:

您正在寻找的是aggregation framework。因此,要从您的数据中获得预期结果,您需要对其执行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
                                }
                    }
                 ])

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

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

【讨论】:

    【解决方案2】:

    很遗憾,我找不到执行此操作的一步查询。所以我把它分成了几个步骤。请注意以下几点:

    1. 我已在我的 json 和查询中将 _id 字段更改为 routeId。
    2. 代码不处理异步。所以在 for 循环中你需要处理它。计数 (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}
      

    最后 - 这是代码。第一部分获取所有不同的 uuid 以及它们各自的最小和最大 routeId,用于 lat 和 lon 匹配。 第二部分循环并检查最小值和最大值是否对应于正确的 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});
     }  
    }
    

    【讨论】:

    • 而我的收藏名为 stack_302,...您需要更改它
    • 感谢庞。不知道为什么,无论我尝试什么,我都会收到格式错误。
    猜你喜欢
    • 2020-05-06
    • 1970-01-01
    • 2018-04-21
    • 2011-04-27
    相关资源
    最近更新 更多