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 个相同的匹配项来:
- 匹配所有符合指定条件的文档。
- 匹配所有展开的 'purchase' 匹配指定的条件。
您可以在没有第一次匹配的情况下使用此聚合,但它可能会有点慢。
你可以看到它是如何工作的如果你注释所有的阶段,然后一个一个取消注释。
在 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 个相同的匹配项来:
- 匹配所有符合指定条件的文档。
- 匹配所有展开的 'purchase' 匹配指定的条件。
您可以在没有第一次匹配的情况下使用此聚合,但它可能会有点慢。
你可以看到它是如何工作的如果你注释所有的阶段,然后一个一个取消注释。