【问题标题】:Mongodb $in against a field of objects of array instead of objects of arrayMongodb $in 针对数组对象字段而不是数组对象
【发布时间】:2014-08-21 14:29:15
【问题描述】:
arr=[{field1:<value1>,field2:<value2}.....]

我想对arrfield1 使用$in 运算符。我知道我可以创建一个虚拟数组并将field1 值推送到虚拟数组中。但是有没有办法对数组的特定字段使用$in 运算符?

arr 数组与集合没有任何关系。

我想查询特定字段上的所有文档,其值在arrfield1 中 - field1 应该在运算符$in 的右侧

例子:

arr=[{name:'foo',location:'NY'},{name:'bar',location:'LA'},{name:'foobar',location:'NZ'}]

db.collection.find({fieldx:<Here I want some method to obtain all documents whose fieldx values are in the location field of arr>})

输出应包含其fieldx 值存在于arrlocation 字段中的文档。

查询的输出应该是

[{... 
    fieldx:'NY',
...
},
{...
    fieldx:'LA',
...
},
{...
    fieldx:'NZ',
...
}]

fieldx 是我要查询的集合中的字段。它不是我提供的数组的一个字段(arr)。我想将它与数组的字段(location)匹配 - arr 我正在提供查询。

【问题讨论】:

  • 只是为了清理你的 cmets,你基本上想做 ` "array": [{ "field1": { "$in": }},{ "field2": { " $in": } }]` 以某种形式的有效语法对吗?这是否意味着“field1”和“field2”都必须很多,还是意味着它们中的任何一个?
  • 我不确定你在暗示什么。我想对类似于 $in 的字段进行查询。但是当 $in 运算符比较给定数组中的整个对象时,我想匹配 $in 右侧给定数组上的单个字段。基本上我的主要需求是在 in 的右侧使用点表示法(在提供给查询的数组上)
  • 这个例子有一定的意义,澄清是人们正在寻找的。所以“fieldx”是文档中的另一个字段,您想知道它是否与您提供的数组中的某些内容相匹配?还是文档中的另一个数组字段?同样,编辑更好。当你做出改变时告诉人们。并使用@username“标记”
  • @NeilLunn fieldx 是我担心的文档中唯一的字段。 arr 与集合无关。我不想将 arr 中的特定字段值提取到新数组中,并针对新数组对 fieldx 执行 $in 查询。有没有更直接的方法?
  • 请回读。你没有正确地解释自己,这就是为什么你还没有答案。我最后的评论非常具体。你有事要解决。

标签: javascript mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

你需要使用dot notation来选择数组中的字段:

db.coll.find({"arr.field1" : { $in : [ 'value1', 'value11' ]}});

此查询将返回数组arr 包含至少一个子文档的所有文档,该子文档的字段field1 的值为value1value11

编辑

关于您的编辑,您不能那样使用 $in 运算符。

来自documentation

$in 运算符选择字段值所在的文档 等于指定数组中的任何值。

如果您在 $in 查询中发送对象数组,它将匹配指定字段包含该对象的文档:

db.coll.find({ a: { $in : [ { b : 1, c: 1}, { b : 2, c: 2}  ]}});

会找到这些文件:

{ 
    _id : ...
    a: { b : 1, c: 1} 
}
{ 
    _id : ...
    a: { b : 2, c: 2} 
}

要获得您真正想要的,最简单的查询方法是从对象数组中提取值,并使用创建的值数组进行查询。

【讨论】:

  • 我想将字段 1 用于运算符 $in 的右侧。如果问题不够清楚,我很抱歉
  • 再说一次,我认为您没有正确理解我的问题。也许我没有说对。我在集合中有一个字段 - queryfield。我有一个与集合无关的数组 - array1 其中包含对象。我想针对array1 的特定字段查询queryfield。该数组不在文档中。
  • 我想避免将值提取到新数组中,看看是否有任何方法可以进行所需的查询。那么没有其他方法(使用 '$in' 与否)更有效地做到这一点?
  • @ma08 提取值并使用 $in 运算符将是进行查询的最简单有效的方法。
【解决方案2】:

您需要从输入数组中提取“位置”字段并将它们提供给 $in

var locs = arr.map(function(x) { return x.location } );
db.collection.find({ "fieldx": { "$in": locs } })

作为参考,我将为您重新编写您的问题:

我有一个包含这样的文档的集合:

{ "fieldx": "NY" }
{ "fieldx": "LA" }
{ "fieldx": "SF" }

我有一个输入数组,定义如下:

var arr = [
    { "name": "foo", "location": "NY"},
    { "name": "bar", "location": "LA"},
    { "name": "foobar", "location": "NZ"}
];

现在我想编写一个查询来查找与我输入的数组中的“位置”字段匹配的所有文档。

我该怎么做?

我试过了:

db.collection.find({ "fieldx": { "$in": arr } })

但这不匹配。

【讨论】:

    【解决方案3】:

    扩展 Neil Lunn 的答案,您也可以在查询中使用 map 函数。

    var arr = [
        { "name": "foo", "location": "NY"},
        { "name": "bar", "location": "LA"},
        { "name": "foobar", "location": "NZ"}
    ];
    
    db.collection.find({ "fieldx": { "$in": arr.map(function(x) { return x.location } ) } })
    

    如果你使用 ES6 语法,那么

    db.collection.find({ "fieldx": { "$in": arr.map(x => x.location ) } })
    

    【讨论】:

      猜你喜欢
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-02
      • 2021-01-09
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多