我的文档结构如下:
{
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
的 map ,按 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)
但这东西不是按升序排列 map 的。
谢谢。
最佳答案
你不能用数组做到这一点,这里的主要问题是你希望“排序”发生在匹配的元素上。如果你想像这样对结果进行排序,那么你需要使用 .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 按数组元素对文档进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28889240/