如何通过索引查询嵌套的 mongodb 数组?

How to make a query on nested mongodb array by index?

文档看起来像这样。

{
    'tid': 1,
    'matches': [{
        'dord': 1,
        'matches': [{
                'tord': 1,
                'score': 11
            },
            {
                'tord': 2,
                'score': 12
            }
        ]
    },
    {
        'dord': 2,
        'matches': [{
                'tord': 1,
                'score': 21
            },
            {
                'tord': 2,
                'score': 22
            }
        ]
    }]
}

可以看出是嵌套数组。我想提取 matches.1.matches.0 处的元素。 结果应如下所示:

{
  'tord': 2, 
  'score': 22
}

我该怎么做?

以下是3种方式

主要问题是我们不能在路径中使用.index

Test code here

查询 1(使用临时变量向前移动)

  • 使用“$arrayElemAt”获取数组索引
  • 获取带有临时变量的文档成员
db.collection.aggregate([
  {
    "$set": {
      "member": {
        "$let": {
          "vars": {
            "m1": {
              "$arrayElemAt": [
                "$matches",
                1
              ]
            }
          },
          "in": {
            "$arrayElemAt": [
              "$$m1.matches",
              1
            ]
          }
        }
      }
    }
  },
  {
    "$project": {
      "member": 1
    }
  }
])

Test code here

Query2(使用临时字段向前移动)

db.collection.aggregate([
  {
    "$set": {
      "member": {
        "$arrayElemAt": [
          "$matches",
          1
        ]
      }
    }
  },
  {
    "$set": {
      "member": {
        "$arrayElemAt": [
          "$member.matches",
          1
        ]
      }
    }
  },
  {
    "$project": {
      "member": 1
    }
  }
])

Test code here

Query3(向前移动文档,向后移动数组“$arrayElemAt”)

db.collection.aggregate([
  {
    "$set": {
      "member": {
        "$arrayElemAt": [
          {
            "$arrayElemAt": [
              "$matches.matches",
              1
            ]
          },
          1
        ]
      }
    }
  },
  {
    "$project": {
      "member": 1
    }
  }
])

我认为1,2更自然,因为你只会向前走,但也有选项3。

我不确定哪个更快,我认为是 2。

使用以下方法

exports.findScore =  async (tid,tord,dord)=>{
    return await tournament.findOne({tid:tid},{matches:{$elemMatch:{tord:tord},{dord:dord}}});
};