0

我需要将 Mongo 文档中的嵌套对象与可能匹配的数组进行匹配。

文件如下所示:

{
  prop1: ...,
  prop2: ...,
  prop3: {
    p3a: 1,
    p3b: 7,
    p3c: 1051
  }
}

我有一系列潜在的匹配项prop3

[ { p3a: 1, p3b: 7, p3c: 1051 }, { p3a: x, p3b: y, p3c: z}, ... ]

有没有办法执行这种匹配?最好使用聚合框架,但即使可以以其他方式执行它,它仍然可以工作。

  • 没有办法改变模型的结构,它有很多与之相关的旧代码,所以即使它不是最优的,我也必须使用它或围绕它工作。
4

1 回答 1

3

您真的不希望为此进行聚合,因为这意味着强制计算将匹配项结合起来。

相反,您想要将源数据从“不合格”键名重新映射为“完全合格”键名以在查询中使用。

例如:

 var arr = [ { p3a: 1, p3b: 7, p3c: 1051 }, { p3a: 'x', p3b: 'y', p3c: 'z'} ]

可以变身:

 arr = arr.map(d => 
   Object.keys(d).reduce((o,k) => Object.assign(o, { [`prop3.${k}`]: d[k] }),{}));

使用 ES6 风格的 JavaScript 更简洁一些,但 mongo shell 不支持更新的语法:

 arr = arr.map(d =>
   Object.entries(d).reduce((o,[k,v]) => ({ ...o, [`prop3.${k}`]: v }),{}) );

现在列出了清单:

[
        {
                "prop3.p3a" : 1,
                "prop3.p3b" : 7,
                "prop3.p3c" : 1051
        },
        {
                "prop3.p3a" : "x",
                "prop3.p3b" : "y",
                "prop3.p3c" : "z"
        }
]

现在您只需查询$or

db.collection.find({ $or: arr })

因此,这就是您需要做的所有事情,因为它$or接受一组条件,并且“列表”中唯一缺少的是要匹配的键尚未使用“点符号”作为完整路径的前缀,包括"prop3".

当常规查询实际上甚至可以使用索引只要这些属性路径不改变就可以有效和高效地完成工作时,没有强制计算之类的“偏好”

于 2018-05-24T11:21:27.323 回答