1

If this is the one questioned before, please let me know. But I couldn't get exact answer from official docs or stackoverflow.

My mongodb document looks like this.

{
    "_id": ObjectId("614e1b600146c86a7d5cb524"),
    "hash": "hash_1",
    "logs": [
        {
            "address": "address_1",
            "topics": [
                "AAA",
            ],
        },
        {
            "address": "address_2",
            "topics": [
                "CCC",
                "DDD",
            ],
        },
    ],
},

{
    "_id": ObjectId("614e1b470146c86a7d5cacd0"),
    "hash": "hash_2",
    "logs": [
        {
            "address": "address_3",
            "topics": [
                "EEE",
                "FFF"
            ],
        },
    ],
}

I only want to query documents that the first value of topics field of an element in logs field equals with certain value, say "CCC". So can be said like this.

results = []
logs.map((log) => log.topics[0] = "CCC" ? results.push(log))
return results

And I only want elements in logs field with that meet the condition above. Is that possible?

1 Answer 1

2
  • $match match the condition to reduce document
  • $project filter array

data

{
    "_id": ObjectId("614e1b600146c86a7d5cb524"),
    "hash": "hash_1",
    "logs": [
      {
        "address": "address_1",
        "topics": [
          "AAA"
        ]
      },
      {
        "address": "address_2",
        "topics": [
          "CCC",
          "DDD"
        ]
      }
    ]
},
{
    "_id": ObjectId("614e1b470146c86a7d5cacd0"),
    "hash": "hash_2",
    "logs": [
      {
        "address": "address_3",
        "topics": [
          "EEE",
          "FFF"
        ]
      }
    ]
}

aggregate

db.collection.aggregate([
  {
    "$match": {
      "logs.topics.0": "CCC"
    }
  },
  {
    $project: {
      hash: 1,
      logs: {
        $filter: {
          input: "$logs",
          as: "log",
          cond: {
            $eq: [
              {
                $arrayElemAt: [
                  "$$log.topics",
                  0
                ]
              },
              "CCC"
            ]
          }
        }
      }
    }
  }
])

result

{
  "_id": ObjectId("614e1b600146c86a7d5cb524"),
  "hash": "hash_1",
  "logs": [
    {
      "address": "address_2",
      "topics": [
        "CCC",
        "DDD"
      ]
    }
  ]
}

mongoplayground

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your quick and correct answer. Btw, I have one more question. What if I want to apply a condition for second element of topics array. It seems like there is no expression like $eq: [{$second: "$$log.topics"},"DDD"] And second is not the last one. There are other elements folllowing like "EEE", "FFF"...
I update my answer. Using $arrayElemAt can get second or third element.
You saved me a day! Thanks a lot @YuTing. I finally was able to get exact elements I wanted with $and expression and your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.