将文档中的嵌套对象与可能匹配的数组匹配

时间:2018-05-24 11:10:34

标签: javascript mongodb mongodb-query aggregation-framework

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

文件如下:

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

我有prop3的潜在匹配数组:

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

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

  • 没有办法改变模型的结构,它有很多旧的代码绑定它,所以即使它不是最优的,我也必须使用它或周围。

1 个答案:

答案 0 :(得分: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接受一系列条件而你的“列表”中唯一缺少的是匹配的键还没有使用"dot notation"作为完整的前缀路径包括"prop3"

当常规查询实际上甚至可以使用索引时,只要那些属性路径不会改变就能有效地完成工作,就不会出现强迫计算的“偏好”