我的文档结构如下:
{
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
按distanceToSpawn
按升序排序。
预期结果:
{
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)
但是这件事没有按升序排序地图。
感谢。
答案 0 :(得分:15)
你不能用数组做到这一点,这里的主要问题是因为你想对匹配的元素进行“排序”。如果您想对此结果进行排序,则需要使用.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 } }
])
这是匹配正确元素并在“排序”操作中考虑它们的唯一方法。默认光标排序只会考虑数组元素中与所选“类型”不匹配的字段值。