我的文档结构如下:
{
map: 'A',
points: [
{
type: 'type1',
distanceToSpawn: 110
},
{
type: 'type4',
distanceToSpawn: 40
},
{
type: 'type6',
distanceToSpawn: 30
}
]
},
{
map: 'B',
points: [
{
type: 'type1',
distanceToSpawn: 100
},
{
type: 'type2',
distanceToSpawn: 60
},
{
type: 'type3',
distanceToSpawn: 25
}
]
},
{
map: 'C',
points: [
{
type: 'type2',
distanceToSpawn: 90
},
{
type: 'type3',
distanceToSpawn: 1
},
{
type: 'type6',
distanceToSpawn: 76
}
]
}
复制代码
我希望得到点数类型为type1的所有地图按距离TDoSpawn按升序排序.
预期结果 :
{
map: 'B',
points: [
{
type: 'type1',
distanceToSpawn: 100
}
]
},
{
map: 'A',
points: [
{
type: 'type1',
distanceToSpawn: 110
}
]
}
复制代码
我尝试过类似的东西:
db.maps.find({'points.type': {$eq : 'type1'}}, {map: 1, 'points.$':1}).sort({'points.distanceToSpawn': 1}).limit(10)
复制代码
但是这个东西没有按升序排序地图.
谢谢.
最佳答案
你不能用数组做到这一点,这里的主要问题是因为你想在匹配的元素上“排序”.如果你想对这样的结果进行排序,那么你需要使用
.aggregate()
.如下:对于现代MongoDB版本:
db.maps.aggregate([
{ "$match": { "points.type": "type1" }},
{ "$addFields": {
"order": {
"$filter": {
"input": "$points",
"as": "p",
"cond": { "$eq": [ "$$p.type", "type1" ] }
}
}
}},
{ "$sort": { "order": 1 } }
])
复制代码
对于MongoDB 2.6到3.0
db.maps.aggregate([
{ "$match": { "points.type": "type1" }},
{ "$project": {
"points": {
"$setDifference": ]
{ "$map": {
"input": "$points",
"as": "p",
"in": { "$cond": [
{ "$eq": [ "$$p.type", "$type1" ] },
"$$p",
false
]}
}},
[false]
]
}
}},
{ "$sort": { "points.distanceToSpawn": 1 } }
])
复制代码
或者在MongoDB 2.6之前的版本效率较低:
db.maps.aggregate([
{ "$match": { "points.type": "type1" }},
{ "$unwind": "$points" },
{ "$match": { "points.type": "type1" }},
{ "$group": {
"_id": "$id",
"points": { "$push": "$points" }
}},
{ "$sort": { "points.ditanceToSpawn": 1 } }
])
复制代码
这是匹配正确元素并在“排序”操作中考虑它们的唯一方法.默认光标排序只会考虑数组元素中与所选“类型”不匹配的字段的值.
相关博文
MongoDB按数组元素对文档进行排序