简体   繁体   English

猫鼬查询以查找多个数组中的匹配元素

[英]Mongoose query to find matching elements in multiple arrays

I have data like this: 我有这样的数据:

{
  name:'string'
  A: [
    {
      D: []
    }
 ],
  B:[
    {
      D:[]
    }
  ],
  C:[
    {
      D:[]
    }
   ]
}

I want to search through all the D arrays in every array of A , B and C for a match. 我想在ABC每个数组中搜索所有D数组以查找匹配项。

I've made this query but it always returns an empty array, so I don't think I did it right. 我进行了此查询,但是它始终返回一个空数组,因此我认为我做的不正确。

model.find({'name':nameVar, $elemMatch:[
    {'A':{'A.D':{$in:[matchVar]}}},
    {'B':{'B.D':{$in:[matchVar]}}},
    {'C':{'C.D':{$in:[matchVar]}}}]},function(err,data){...

How can I return all the elements of A , B and C where matchVar is inside D ? 如何返回matchVarD内的ABC所有元素?


EDIT: 编辑:

It looks like this isn't even possible? 看来这甚至是不可能的? https://groups.google.com/forum/#!topic/mongodb-user/rUHK43Xtp88 https://groups.google.com/forum/#!topic/mongodb-user/rUHK43Xtp88

But I'm still holding out for an answer 但是我仍然在寻找答案

Well if I understand what you are actually asking in your question, then with this data: 好吧,如果我了解您实际上在问您的问题,那么请使用以下数据:

{ 
    "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" ] } ] 
}

You find the first document like so: 您会找到第一个文档,如下所示:

db.collection.find({
    "$or": [
         { "A.D": "A" },
         { "B.D": "A" },
         { "C.D": "A" },
     ]
})

Or perhaps you meant that the other way around, so to match the second document only: 也许您的意思是相反的,所以只匹配第二个文档:

db.collection.find({
    "$and": [
         { "A.D": "C" },
         { "B.D": "C" },
         { "C.D": "C" },
     ]
})

The link that you reference actually refers to some different behavior with the $all operator which has been changed in the 2.6 release to do what it really should be doing. 您引用的链接实际上表示$all运算符的某些不同行为,该行为已在2.6版本中更改为执行其应做的工作。 But that doesn't really apply to this question how you have presented it. 但这实际上不适用于您如何提出此问题。

So if you want any of the arrays to match then use $or around each query statement. 因此,如果要使任何数组匹配,则在每个查询语句周围使用$or If on the other hand you want only to match where all of the arrays contain your match, then use the $and operator instead. 另一方面,如果您只想匹配所有数组包含匹配项的位置,则使用$and运算符。

It's only logical ;) 这只是合乎逻辑的;)


EDIT 编辑

Keep in mind that .find() is all about matching documents. 请记住, .find()都是与匹配文档有关的。 When you actually want to match elements within arrays that extend beyond one match only then you use aggregate in order to filter the content: 当您实际上只想匹配超出一个匹配项的数组中的元素时,可以使用聚合来过滤内容:

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" 
        }}
    }}
])

And that will return results: 这将返回结果:

{
    "_id" : ObjectId("53473e6ecb495e216c98292b"),
    "doc" : [
            {
                    "key" : "B",
                    "value" : {
                            "D" : "B"
                    }
            }
    ]
}
{
    "_id" : ObjectId("53473d87cb495e216c982929"),
    "doc" : [
            {
                    "key" : "A",
                    "value" : {
                            "D" : "B"
                    }
            },
            {
                    "key" : "C",
                    "value" : {
                            "D" : "B"
                    }
            }
    ]
}

So I got the two documents with only the rows from the arrays that matched the condition. 因此,我从匹配条件的数组中仅获得了两行文档。 Not in the same format as it went in, but then end result is the same. 格式与输入时不同,但最终结果相同。

You get some additional features with 2.6 that could be used ( I think, I haven't tried ) to re-shape again back into the form, but generally speaking, then yes the result is possible. 您可以使用2.6获得一些附加功能(我想,我还没有尝试过)可以再次将其重新成形为表单,但总的来说,结果是可能的。 It's a lot of work, but as you can see from the re-shaped form it also gives an indication of the format the data "should" probably be in if you want to query like this. 这需要做很多工作,但是从改形后的表格中可以看出,如果要进行这样的查询,它还可以指示数据“应该”位于的格式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM