Saurav Pathak
Saurav Pathak

Reputation: 836

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

Document looks like this.

{
    '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
            }
        ]
    }]
}

You can see that it is a nested array. I want to extract the element at matches.1.matches.0 . Result should look like this:

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

How do I do this ?

Upvotes: 0

Views: 54

Answers (2)

Use the following method

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

Upvotes: 0

Takis
Takis

Reputation: 8695

Bellow are 3 ways

The main problem is that we cant use .index in path.

Test code here

Query1 (move forward with temp variables)

  • get array index with "$arrayElemAt"
  • get document member with a temp variable
db.collection.aggregate([
  {
    "$set": {
      "member": {
        "$let": {
          "vars": {
            "m1": {
              "$arrayElemAt": [
                "$matches",
                1
              ]
            }
          },
          "in": {
            "$arrayElemAt": [
              "$$m1.matches",
              1
            ]
          }
        }
      }
    }
  },
  {
    "$project": {
      "member": 1
    }
  }
])

Test code here

Query2 (move forward with temp fields)

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

Test code here

Query3 (move forward to project the documents,move backwards for the arrays "$arrayElemAt")

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

The more natural are the 1,2 i think because you only move forward, but there is option 3 also.

Which is the faster i dont know for sure, i think the 2.

Upvotes: 1

Related Questions