【问题标题】:Need help on mongo aggregation query需要有关 mongo 聚合查询的帮助
【发布时间】:2021-05-15 01:38:45
【问题描述】:

以下是示例数据:

[{
        "outdoor": {
            "location": {
                "type": "Point",
                "coordinates": [
                    -92.41151,
                    35.11683
                ]
            }
        },
        "geoHash": "dr72jwgnbbst", "status":"Active","customerId":"8047380094","locationId":"A0"

    },
    {
        "outdoor": {
            "location": {
                "type": "Point",
                "coordinates": [
                    -89.58342,
                    36.859161
                ]
            }
        },
        "geoHash": "dn6qtkr5xk8m", "status":"Pending","customerId":"8047380094","locationId":"A1"
    },
    {
        "outdoor": {

            "location": {
                "type": "Point",
                "coordinates": [
                    -86.038762,
                    36.519016
                ]
            }
        },
        "geoHash": "dn6zf0h6xtcp", "status":"Active","customerId":"8047380094","locationId":"A2"
    },
    {
        "outdoor": {
            "location": {
                "type": "Point",
                "coordinates": [
                    -98.3081936,
                    26.2143207
                ]
            }
        },
        "geoHash": "9udj4unjmp9f", "status":"Pending","customerId":"8047380094","locationId":"A3"
    },
    {
        "outdoor": {
            "location": {
                "type": "Point",
                "coordinates": [
                    -98.5377275,
                    29.4878928
                ]
            }
        },
        "geoHash": "9v1zv8p52t8u", "status":"Pending","customerId":"8047380094","locationId":"A4"
    },
    {
        "outdoor": {
            "location": {
                "type": "Point",
                "coordinates": [
                    -73.7018126,
                    42.641387
                ]
            }
        },
        "geoHash": "dreddfeup69m", "status":"Pending","customerId":"8047380094","locationId":"A5"
    },
    {
        "outdoor": {
            "location": {
                "type": "Point",
                "coordinates": [
                    -111.865295,
                    33.431942
                ]
            }
        },
        "geoHash": "9tbqnqn5jtwq", "status":"Active","customerId":"8047380094","locationId":"A6"
    },
    {
        "outdoor": {
            "location": {
                "type": "Point",
                "coordinates": [
                    -79.810763,
                    34.174603
                ]
            }
        },
        "geoHash": "dnp4rv796rtz", "status":"Active","customerId":"8047380094","locationId":"A7"
    }
]

目前我们正在运行 2 个查询:

查询 1 - 此查询将按 geoHash 子字符串分组的状态给出计数。

db.locations.aggregate([{"$match": {"customerId": "8047380094"}}, {"$project": {"status": 1, "geoHash": {"$substr": ["$geoHash", 0, 2]}}}, {"$group": {"_id": {"geoHash": "$geoHash", "status": "$status"}, "statusCount": {"$sum": 1}}}],
{
  "allowDiskUse": true
});

输出 1:

{ "_id" : { "geoHash" : "dr", "status" : "Active" }, "statusCount" : 1 }
{ "_id" : { "geoHash" : "dr", "status" : "Pending" }, "statusCount" : 1 }
{ "_id" : { "geoHash" : "dn", "status" : "Active" }, "statusCount" : 2 }
{ "_id" : { "geoHash" : "dn", "status" : "Pending" }, "statusCount" : 1 }
{ "_id" : { "geoHash" : "9u", "status" : "Pending" }, "statusCount" : 1 }
{ "_id" : { "geoHash" : "9v", "status" : "Pending" }, "statusCount" : 1 }
{ "_id" : { "geoHash" : "9t", "status" : "Active" }, "statusCount" : 1 }

查询 2 - 我们有一个查询来获取 geohash 组的第一个位置坐标。

db.locations.aggregate([{"$match": {"customerId": "8047380094"}}, {"$project": {"geoHash": {"$substr": ["$geoHash", 0, 2]}, "locations": "$outdoor.location.coordinates"}}, {"$group": {"_id": "$geoHash", "locations": {"$push": "$locations"}}}, {"$project": {"_id": 1, "locations": {"$arrayElemAt": ["$locations", 0]}}}],
{
  "allowDiskUse": true
});

输出 2:

{ "_id" : "dr", "locations" : [ -92.41151, 35.11683 ] }
{ "_id" : "dn", "locations" : [ -89.58342, 36.859161 ] }
{ "_id" : "9u", "locations" : [ -98.3081936, 26.2143207 ] }
{ "_id" : "9v", "locations" : [ -98.5377275, 29.4878928 ] }
{ "_id" : "9t", "locations" : [ -111.865295, 33.431942 ] }

问题 1: 有没有我们可以将两个查询合并为 1 并在一个查询中获得两个输出?

问题 2: 如果总数为 1(不是按状态),我们还需要获取 locationId 吗?我们如何在同一个查询中实现这一点? 在上述情况下, 对于“9u”,我们需要返回 A3 对于“9v”,我们需要返回 A4 对于“9t”,我们需要返回 A6

注意:我们正在使用带有 spring mongo 的 spring boot 应用程序。

【问题讨论】:

  • 如果没有排序,文档可能会或可能不会以相同的顺序返回,什么决定了哪个位置是“第一个”?什么是“总数”?集合中的文档数量,每个用户的数量,每个哈希子字符串?
  • 是的,总计 = 否。每个客户每个哈希子字符串的金额
  • @pal.nag 这个答案对你有帮助吗?

标签: mongodb mongodb-query aggregation-framework spring-data-mongodb


【解决方案1】:

我没有去你试图达到的目标,因为问题没有提到它。但是对于你们两个问题,我可以回答

  1. 您可以使用$facet 来创建多个聚合管道
  2. 通过使用第一个$facet阶段,您可以使用附加阶段来获取您的locationId;

这里是代码

{
    $project: {
      firstQuery: 1,
      secondQuery: {
        $map: {
          input: "$secondQuery",
          as: "s",
          in: {
            $mergeObjects: [
              "$$s",
              {
                $arrayElemAt: [
                  {
                    $map: {
                      input: {
                        $filter: {
                          input: "$firstQuery",
                          as: "f",
                          cond: { $eq: ["$$f._id.geoHash", "$$s._id" ] }
                        }
                      },
                      in: { locationId: "$$this.locationId" }
                    }
                  },
                  0
                ]
              }
            ]
          }
        }
      }
    }
  }

工作Mongo playground

注意:确保{ $eq: ["$$f._id.geoHash", "$$s._id" ] } 会给出一个唯一的对象。否则需要另一个想法。而且我觉得您发布的两个查询更像是相同的。所以可以有一个简单的解决方案。但我根据你发布的问题回答了

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 2018-07-18
    • 2011-04-18
    • 1970-01-01
    相关资源
    最近更新 更多