You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB查询:匹配嵌套对象任意数组含指定字符串/正则的文档

MongoDB 动态键嵌套数组匹配查询方案

问题场景

现有同结构的MongoDB集合,文档结构示例如下:

{
  _id: '1',
  text: 'xxxxxxxc',
  choices: {
    a: ['xxx','yyy','zzz'],
    b: ['aaa','bbb','ccc'],
    c: ['lll','mmm','ddd'],
  }
}

// 大量其他同结构文档...

{
  _id: '2',
  text: 'xxxxxxxc',
  choices: {
    a: ['ooo','sss','qqq'],
    b: ['iii','hhh','ggg'],
    c: ['ddd','eee','fff'],
  }
}

核心查询需求:

  • 遍历集合所有文档,判断choices字段下任意动态键对应的数组中,是否存在元素匹配指定字符串/正则规则
  • 只要任意一个数组存在匹配元素,就返回对应文档;无匹配则不返回
  • 约束:choices下的键名不固定(除a/b/c外可能后续新增其他键),无法提前枚举所有键写死查询条件
  • 示例:查询值为'yyy'时,需要返回_id:1的文档(其choices.a包含该值),不返回_id:2的文档

实现方案

因为choices的键是动态的,不能写死字段路径,分场景选择对应写法即可:

1. 精确匹配字符串场景

用$objectToArray把choices对象转成键值对数组,再判断任意值数组里是否包含目标值即可,查询语句示例:

db.collection.find({
  $expr: {
    $gt: [
      {
        $size: {
          $filter: {
            input: { $objectToArray: "$choices" },
            cond: {
              $in: ["yyy", "$$this.v"]
            }
          }
        }
      },
      0
    ]
  }
})

逻辑说明:

  • $objectToArray: "$choices"会把动态键的对象转成[{k:'a', v:['xxx','yyy','zzz']}, {k:'b', v:[...]}...]结构,不需要提前知道键名
  • $filter筛选出v数组(也就是原来每个键对应的数组)里包含目标值的项
  • 只要筛选结果长度大于0,就说明存在匹配项,返回文档

2. 正则匹配场景

如果需要用正则做模糊匹配,把上面的$in替换成$regexMatch即可,示例(匹配所有以yy开头的元素):

db.collection.find({
  $expr: {
    $gt: [
      {
        $size: {
          $filter: {
            input: { $objectToArray: "$choices" },
            cond: {
              $gt: [
                {
                  $size: {
                    $filter: {
                      input: "$$this.v",
                      cond: {
                        $regexMatch: {
                          input: "$$this",
                          regex: /^yy/
                        }
                      }
                    }
                  }
                },
                0
              ]
            }
          }
        }
      },
      0
    ]
  }
})

如果使用MongoDB 5.0及以上版本,还可以用$anyElementTrue简化写法:

// 精确匹配简化版
db.collection.find({
  $expr: {
    $anyElementTrue: {
      $map: {
        input: { $objectToArray: "$choices" },
        in: { $in: ["yyy", "$$this.v"] }
      }
    }
  }
})

// 正则匹配简化版
db.collection.find({
  $expr: {
    $anyElementTrue: {
      $map: {
        input: { $objectToArray: "$choices" },
        in: {
          $anyElementTrue: {
            $map: {
              input: "$$this.v",
              in: { $regexMatch: { input: "$$this", regex: /^yy/ } }
            }
          }
        }
      }
    }
  }
})

优化提示:如果集合数据量很大,可以给choices字段加通配符索引优化查询性能,建索引语句:db.collection.createIndex({"choices.$**": 1})


内容的提问来源于stack exchange,提问作者loop loopertzg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 02:15:41