如何匹配嵌入式数组中的字符串或 MongoDB 中的文档?

How to match string within embedded array or doc in MongoDB?

找了一整天,我怀疑MongoDB是否能满足以下要求:

问:如何过滤掉满足以下条件的文档?

id_1: first_school, students_replies: [
    {Date:20210101, replies: [
        {name: jack, reply: 'I do not like this idea'},
        {name: jason, reply: 'I would rather stay at home'},
        {name: charles, reply: 'I have an plan to improve'},
        ]}, 
    {Date:20210401, replies: [
        ...]}, 
    {Date:20210801, replies: [
        ...]},
]

id_2: second_shool, students_replies: [..]
id_3: third_shool, students_replies: [...]

Mongoplayground

使用$slice$regex

对于您的示例,这变为:

db.collection.aggregate([
  // project only the last reply
  {
    "$project": {
      key: 1,
      last_reply: {
        "$slice": [
          "$students_replies",
          -1
        ]
      }
    }
  },
  // filter the documents
  {
    "$match": {
      "last_reply.replies.name": {
        "$regex": "ason"
      }
    }
  }
])

https://mongoplayground.net/p/a9piw2WQ8n6

由于您需要 students_replies 的最后一个数组元素,请使用 $arrayElemAt

db.collection.aggregate([
  {
    "$match": {
      $expr: {
        $regexMatch: {
          input: {
            $reduce: {
              input: {
                $arrayElemAt: [
                  "$students_replies.replies",
                  -1
                ]
              },
              initialValue: "",
              in: {
                $concat: [
                  "$$value",
                  "$$this.name",
                  ","
                ]
              }
            }
          },
          regex: "ason"
        }
      }
    }
  },
  {
    "$project": {
      "students_replies": 0
    }
  }
])

mongoplayground


另一个答案

db.collection.aggregate([
  {
    $match: {
      $expr: {
        $ne: [
          {
            $filter: {
              input: {
                $map: {
                  input: {
                    $arrayElemAt: [
                      "$students_replies.replies",
                      -1
                    ]
                  },
                  as: "r",
                  in: "$$r.name"
                }
              },
              as: "s",
              cond: {
                $regexMatch: {
                  input: "$$s",
                  regex: "ason"
                }
              }
            }
          },
          []
        ]
      }
    }
  },
  {
    "$project": {
      "students_replies": 0
    }
  }
])

mongoplayground