mongoose 在MongoDB中查找多个同名嵌套字段中的值

1bqhqjot  于 2022-11-13  发布在  Go
关注(0)|答案(1)|浏览(208)

在某些文档中,我有一个结构复杂的属性,如:

{
  content: {
    foo: {
      id: 1,
      name: 'First',
      active: true 
    },
    bar: {
      id: 2,
      name: 'Second',
      active: false 
    },
    baz: {
      id: 3,
      name: 'Third',
      active: true 
    },
}

我尝试进行一个查询,该查询可以在不同的二级对象foobarbaz中查找字段name中具有给定值的所有文档
我想解决办法可能是:

db.getCollection('mycollection').find({ $or: [
    {'content.foo.name': 'First'},
    {'content.bar.name': 'First'},
    {'content.baz.name': 'First'}
]})

但是我想做一个动态的,不需要指定嵌套字段的键名,也不需要在每一行中重复要查找的值。
如果字段名称上的某些正则表达式可用,则解决方案可能是:

db.getCollection('mycollection').find({'content.*.name': 'First'}) // Match
db.getCollection('mycollection').find({'content.*.name': 'Third'}) // Match
db.getCollection('mycollection').find({'content.*.name': 'Fourth'}) // Doesn't match

有什么办法吗?

zd287kbt

zd287kbt1#

如果你事先不知道你的键,我会说这是一个糟糕的模式,我个人建议把它改为数组结构。
不管你能做什么,你都可以使用聚合$objectToArray操作符,然后查询新创建的对象。

db.collection.aggregate([
  {
    $addFields: {
      arr: {
        "$objectToArray": "$content"
      }
    }
  },
  {
    $match: {
      "arr.v.name": "First"
    }
  },
  {
    $project: {
      arr: 0
    }
  }
])

Mongo Playground
另一种可以采用的方法是创建一个通配符文本索引,然后执行$text查询来搜索名称,显然,这会带来文本索引/查询的限制,可能不适合您的用例。

相关问题