![](/img/trans.png)
[英]Find the matching elements between multiple arrays (more than 2) in JavaScript
[英]Mongoose query to find matching elements in multiple arrays
我有这样的数据:
{
name:'string'
A: [
{
D: []
}
],
B:[
{
D:[]
}
],
C:[
{
D:[]
}
]
}
我想在A
, B
和C
每个数组中搜索所有D
数组以查找匹配项。
我进行了此查询,但是它始终返回一个空数组,因此我认为我做的不正确。
model.find({'name':nameVar, $elemMatch:[
{'A':{'A.D':{$in:[matchVar]}}},
{'B':{'B.D':{$in:[matchVar]}}},
{'C':{'C.D':{$in:[matchVar]}}}]},function(err,data){...
如何返回matchVar
在D
内的A
, B
和C
所有元素?
编辑:
看来这甚至是不可能的? https://groups.google.com/forum/#!topic/mongodb-user/rUHK43Xtp88
但是我仍然在寻找答案
好吧,如果我了解您实际上在问您的问题,那么请使用以下数据:
{
"name" : "string",
"A" : [ { "D" : [ "B" ] } ],
"B" : [ { "D" : [ "A" ] } ],
"C" : [ { "D" : [ "B" ] } ]
},
{
"name" : "string",
"A" : [ { "D" : [ "C" ] } ],
"B" : [ { "D" : [ "C" ] } ],
"C" : [ { "D" : [ "C" ] } ]
},
{
"name" : "string",
"A" : [ { "D" : [ "C" ] } ],
"B" : [ { "D" : [ "B" ] } ],
"C" : [ { "D" : [ "C" ] } ]
}
您会找到第一个文档,如下所示:
db.collection.find({
"$or": [
{ "A.D": "A" },
{ "B.D": "A" },
{ "C.D": "A" },
]
})
也许您的意思是相反的,所以只匹配第二个文档:
db.collection.find({
"$and": [
{ "A.D": "C" },
{ "B.D": "C" },
{ "C.D": "C" },
]
})
您引用的链接实际上表示$all
运算符的某些不同行为,该行为已在2.6版本中更改为执行其应做的工作。 但这实际上不适用于您如何提出此问题。
因此,如果要使任何数组匹配,则在每个查询语句周围使用$or
。 另一方面,如果您只想匹配所有数组包含匹配项的位置,则使用$and
运算符。
这只是合乎逻辑的;)
请记住, .find()
都是与匹配文档有关的。 当您实际上只想匹配超出一个匹配项的数组中的元素时,可以使用聚合来过滤内容:
db.collection.aggregate([
// Matching documents still makes sense to reduce the pipeline
{ "$match": {
"$or": [
{ "A.D": "B" },
{ "B.D": "B" },
{ "C.D": "B" },
]
}},
// Unwind all of the arrays
{ "$unwind": "$A" },
{ "$unwind": "$B" },
{ "$unwind": "$C" },
{ "$unwind": "$A.D" },
{ "$unwind": "$B.D" },
{ "$unwind": "$C.D" },
// Set up for the next stage by adding "type"
{ "$project": {
"A": 1,
"B": 1,
"C": 1,
"type": { "$cond": [1, ["A","B","C"], 0] }
}},
// Unwind that array so every document copied for each type
{ "$unwind": "$type" },
// Do some conditional re-shaping to key/values
{ "$project": {
"key": { "$cond": [
{ "$eq": [ "$type", "A" ] },
"A",
{ "$cond": [
{ "$eq": [ "$type", "B" ] },
"B",
{ "$cond": [
{ "$eq": [ "$type", "C" ] },
"C",
false
]}
]}
]},
"value": { "$cond": [
{ "$eq": [ "$type", "A" ] },
"$A",
{ "$cond": [
{ "$eq": [ "$type", "B" ] },
"$B",
{ "$cond": [
{ "$eq": [ "$type", "C" ] },
"$C",
false
]}
]}
]}
}},
// Filter for only the matching documents
{ "$match": { "value.D": "B" } },
// Just group that by id
{ "$group": {
"_id": "$_id",
"doc": { "$push": {
"key": "$key",
"value": "$value"
}}
}}
])
这将返回结果:
{
"_id" : ObjectId("53473e6ecb495e216c98292b"),
"doc" : [
{
"key" : "B",
"value" : {
"D" : "B"
}
}
]
}
{
"_id" : ObjectId("53473d87cb495e216c982929"),
"doc" : [
{
"key" : "A",
"value" : {
"D" : "B"
}
},
{
"key" : "C",
"value" : {
"D" : "B"
}
}
]
}
因此,我从匹配条件的数组中仅获得了两行文档。 格式与输入时不同,但最终结果相同。
您可以使用2.6获得一些附加功能(我想,我还没有尝试过)可以再次将其重新成形为表单,但总的来说,结果是可能的。 这需要做很多工作,但是从改形后的表格中可以看出,如果要进行这样的查询,它还可以指示数据“应该”位于的格式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.