MongoDB 数组中的地理空间查询 returns 总是完整的文档

MongoDB Geospatial query within an array returns always the full doc

在 MongoDB 中有一个看起来像这样的集合:

{
"_id" : "7613035010550",
"purchases" : [ 
    {
        "date" : ISODate("2017-04-15T14:15:00.000Z"),
        "coords" : {
            "lon" : 43.729604,
            "lat" : 1.416017
        },
        "metar" : {},
        "quantity" : 1,
        "price" : 2.31
    }, 
    {
        "date" : ISODate("2017-05-02T16:23:00.000Z"),
        "coords" : {
            "lon" : 43.722862,
            "lat" : 1.415837
        },
        "metar" : {},
        "quantity" : 6,
        "price" : 12
    }, 
    {
        "date" : ISODate("2017-05-02T18:32:00.000Z"),
        "coords" : {
            "lon" : 46.307353,
            "lat" : 3.28937
        },
        "metar" : {},
        "quantity" : 2,
        "price" : 5
    }
],
"rates" : [ 
    {
        "value" : 5
    }, 
    {
        "value" : 4
    }, 
    {
        "value" : 5
    }, 
    {
        "value" : 2
    }
]
}

并且想查询 return 仅在某个点周围的定义半径(即 5 公里)内完成的购买并且仅针对一个 id...但我不知道如何来处理这种查询。

试试这个查询:

db.getCollection('stats').find({"purchases.coords":{$geoWithin:{$centerSphere: [[43.688935, 1.401541], 25 / 6378.1]}}})

但是 return 是整个文档...我希望能够 return 类似于围绕定义的半径进行的一系列购买,即我的例子中只有这两个:

        {
        "date" : ISODate("2017-04-15T14:15:00.000Z"),
        "coords" : {
            "lon" : 43.729604,
            "lat" : 1.416017
        },
        "metar" : {},
        "quantity" : 1,
        "price" : 2.31
    }, 
    {
        "date" : ISODate("2017-05-02T16:23:00.000Z"),
        "coords" : {
            "lon" : 43.722862,
            "lat" : 1.415837
        },
        "metar" : {},
        "quantity" : 6,
        "price" : 12
    }

我怎样才能实现这种查询...或者...如何定义我的集合才能进行这种查询?

谢谢,

JL

为了您的目的,我建议使用阶段聚合 project and unwind

现在无法检查,但应该如下所示:

db.getCollection('stats').aggregate([
    {'$match': {
        "purchases.coords": {$geoWithin:{$centerSphere: [[43.688935, 1.401541], 25 / 6378.1]}}
    }},
    {'$project': {
        "_id": 0, // 0 - if you don't need document id
        "purchases": 1,
    }},
    {'$unwind': "$purchases"},
    {'$match': {
        "purchases.coords": {$geoWithin:{$centerSphere: [[43.688935, 1.401541], 25 / 6378.1]}}
    }},
])

我使用了 2 个相同的匹配项来:

  1. 匹配所有符合指定条件的文档。
  2. 匹配所有展开的 'purchase' 匹配指定的条件。

您可以在没有第一次匹配的情况下使用此聚合,但它可能会有点慢。

你可以看到它是如何工作的如果你注释所有的阶段,然后一个一个取消注释。