假设在集合中我有以下文件:
[
{"title": "t1", "fingerprint":[1, 2, 3]},
{"title": "t2", "fingerprint":[4, 5, 6]}
]
我想查询文档,其中指定位置的指纹中至少有一个元素等于我的查询数组。
例如:
查询([1,7,9])应该返回[{"title": "t1", "fingerprint":[1, 2, 3]}]
查询([1,5,9])应该返回[{"title": "t1", "fingerprint":[1, 2, 3]}, {"title": "t2", "fingerprint":[4, 5, 6]}]
但是查询([5,1,9])应该不返回任何记录,因为两个记录在指纹数组中的任何位置都没有相同的值。 如何编写给定的查询?
答案 0 :(得分:2)
当您尝试仅匹配序列[1 2,3]出现在values
字段中且仅按照确切顺序排列的数组时,您可以这样做:
db.testcol.find()
{ "_id" : "first", "value" : [ 1, 2, 3 ] }
{ "_id" : "second", "value" : [ 4, 5, 6 ] }
{ "_id" : "third", "value" : [ 1, 12, 13 ] }
{ "_id" : "fourth", "value" : [ 3, 2, 1 ] }
{ "_id" : "fifth", "value" : [ 1, 12, 13, 2, 3 ] }
{ "_id" : "sixth", "value" : [ 3, 2, 1, 2, 3 ] }
> db.testcol.aggregate([{$addFields:{
cmp: {$in:[
{$literal:[1,2,3]},
{$map: {
input:{$range:[0, {$subtract:[{$size:"$value"},2]}]},
as:"l",
in: {$slice: [ "$value", "$$l", 3] }
}}
]}
}}])
{ "_id" : "first", "value" : [ 1, 2, 3 ], "cmp" : true }
{ "_id" : "second", "value" : [ 4, 5, 6 ], "cmp" : false }
{ "_id" : "third", "value" : [ 1, 12, 13 ], "cmp" : false }
{ "_id" : "fourth", "value" : [ 3, 2, 1 ], "cmp" : false }
{ "_id" : "fifth", "value" : [ 1, 12, 13, 2, 3 ], "cmp" : false }
{ "_id" : "sixth", "value" : [ 3, 2, 1, 2, 3 ], "cmp" : true }
$addFields
阶段的作用是检查[1,2,3]
是否出现在从value
数组的位置0开始的三个元素数组的列表中,并向前移动到结束前的两个位置。< / p>
正如您所看到的,添加$match
阶段来过滤掉cmp
不正确的文档现在变得微不足道了。
答案 1 :(得分:1)
您可以使用.$index
表示法执行此类搜索。
query([1, 7, 9])
db.coll.find({$or: [{"fingerprint.0": 1}, {"fingerprint.1": 7 }, {"fingerprint.2": 9}]})
{ "_id" : ObjectId("59170da907e34e73c0c93a9b"), "title" : "t1", "fingerprint" : [ 1, 2, 3 ] }
query([1, 5, 9])
db.coll.find({$or: [{"fingerprint.0": 1}, {"fingerprint.1": 5 }, {"fingerprint.2": 9}]})
{ "_id" : ObjectId("59170da907e34e73c0c93a9b"), "title" : "t1", "fingerprint" : [ 1, 2, 3 ] }
{ "_id" : ObjectId("59170da907e34e73c0c93a9c"), "title" : "t2", "fingerprint" : [ 4, 5, 6 ] }
答案 2 :(得分:0)
$ in运算符用于将值与值列表进行匹配。
根据上述说明,请尝试在MongoDB shell中执行以下查询
db.collection.find({fingerprint:{$in:[1,7,9]}})