我的文档 struct 如下:

{
    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相关问答推荐

MongoDB索引使用

MongoDB/Mongoose查询:使用优先约束检索从位置A到位置B的路径

如何使用聚合管道查找未销售但存在于产品详细信息集合中的产品的ID

尽管前一阶段输出文档,$group stage 仍返回零文档

分组前的 MongoDb 聚合总数

mongo:在 mongodb 6.0 docker 容器上找不到命令

MongoDB 支持的最 Big Data 库数

MongoDB 存储大量指标/分析数据的方法

无法提取地理键,经度/纬度超出范围

你如何在 Kubernetes 上设置 Mongo 副本集?

如何在 MongoDb 中使用杰克逊将日期字段存储为 ISODate()

mongod 和 mongo 命令在 Windows 10 上不起作用

MongoDB 批处理操作的最大大小是多少?

单个模式数组中的多个模式引用 - mongoose

mongoose字符串到 ObjectID

MongoDb 连接被拒绝

brew install mongodb 错误:Cowardly refusing to `sudo brew install' Mac OSX Lion

使用 C# 聚合 $lookup

无法从 mongodb 中删除集合

哪个数据库适合我的应用程序 mysql 或 mongodb ?使用 Node.js 、 Backbone 、 Now.js