Mongodb $in 针对数组对象字段而不是数组对象

Posted

技术标签:

【中文标题】Mongodb $in 针对数组对象字段而不是数组对象【英文标题】:Mongodb $in against a field of objects of array instead of objects of array 【发布时间】: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 查询。有没有更直接的方法? 请回读。你没有正确地解释自己,这就是为什么你还没有答案。我最后的评论非常具体。你有事要解决。 【参考方案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 )  )

【讨论】:

以上是关于Mongodb $in 针对数组对象字段而不是数组对象的主要内容,如果未能解决你的问题,请参考以下文章

如何修改我的 mongodb/mongoose 查询,使其采用对象数组而不是字符串数组?

MongoDB 聚合 - 满足所有对象数组而不是至少一个的查询集合

Mongodb检查数组的子文档中是否存在字段

MongoDB - 基于嵌套数组的字段值更新数组对象中的字段

根据数组下标在MongoDB中修改数组元素

将数组中对象的字段添加到同一数组中对象的另一个字段MongoDB