首页 文章

Mongodb比较对象数组键

提问于
浏览
1

我在mongodb集合中保存了以下示例文档:

{
       _id:"3213dsadsa812321",
       files: [ 
       {_id: "99300", path:"C:\Filename01.txt"},
       {_id: "99301", path:"C:\Filename02.txt"},
       {_id: "99302", path:"C:\Filename03.txt"},
       {_id: "99303", path:"C:\Filename04.txt"},
       ]
   }

我有以下数组var dynFiles:

[          
       {_id: "1", path:"C:\folder\textfile01.txt"},
       {_id: "2", path:"C:\folder\textfile02.txt"},
       {_id: "3", path:"C:\folder\textfile03.txt"},
       {_id: "4", path:"C:\Filename04.txt"},
  ]

是否有可能找到任何mongodb文档对象数组路径键是否匹配任何dynFiles var路径键?

换句话说,基于给定的上述记录_id:db中的“99303”应该返回,因为它与var对象数组_id匹配:“4” .

预期结果:

[ {_id: "99303", path:"C:\Filename04.txt"} ]

经过广泛的研究后,我编写了以下查询,但不幸的是,它将文档files.path键与特定的对象数组键进行比较并没有多大帮助,而我需要它将files.path与dynFiles的所有路径进行比较 . 在此先感谢您的帮助和时间

{ 'files.path': {$eq: dynFiles.path} }

2 回答

  • 0

    您需要另一个仅包含映射路径的数组,这可以使用JavaScript的 .map() 方法派生 . 然后,此数组将在mongo查询中用作 $in 运算符值 . 以下说明了这一点:

    var dynFiles = [          
           {_id: "1", path:"C:\folder\textfile01.txt"},
           {_id: "2", path:"C:\folder\textfile02.txt"},
           {_id: "3", path:"C:\folder\textfile03.txt"},
           {_id: "4", path:"C:\Filename04.txt"},
        ],
        paths = dynFiles.map(function(f){ return f.path; });
    
    db.collection.find({"files.path": {"$in": paths }})
    
  • 0

    使用.aggregate()方法 .

    首先,您需要使用.map()方法返回"path"数组 .

    > var dynFiles = [          
    ...        {_id: "1", path:"C:\folder\textfile01.txt"},
    ...        {_id: "2", path:"C:\folder\textfile02.txt"},
    ...        {_id: "3", path:"C:\folder\textfile03.txt"},
    ...        {_id: "4", path:"C:\Filename04.txt"},
    ...   ];
    > var paths = dynFiles.map(function(element) {
    ... return element.path;
    ... });
    > paths
    [
            "C:\folder\textfile01.txt",
            "C:\folder\textfile02.txt",
            "C:\folder\textfile03.txt",
            "C:Filename04.txt"
    ]
    

    然后是聚合查询:

    您只需要管道中的一个阶段,即$project阶段,您可以使用$map运算符返回"path"在"dynFiles"中的子文档数组 . 要检查给定"path"是否在"dynFiles"中,请在$cond表达式中使用$setIsSubset运算符 . 您需要 $setIsSubset 的原因是因为您无法在 $cond 表达式中使用 $in 运算符 . 当然 $setIsSubset 运算符需要两个数组作为参数,您需要使用 $map 运算符来返回一个元素数组 . 当然$literal运算符允许您将文字数组分配给 $map 中的"input" . 此外,您需要使用$setDifference此处从数组中过滤掉所有 false ,只要被过滤的数据是"unique"就可以了 .

    db.paths.aggregate([
        { "$project": { 
            "files": { 
                "$setDifference": [
                    { "$map": { 
                        "input": "$files", 
                        "as": "file", 
                        "in": { 
                            "$cond": [ 
                                { "$setIsSubset": [ 
                                    { "$map": {
                                        "input": { "$literal": [ "A" ] },
                                        "as": "el", 
                                        "in": "$$file.path"
                                    }}, 
                                    paths
                                ] },
                                "$$file",
                                false 
                            ]
                        }
                    }}, 
                    [false]
                ]
            }
        }}
    ])
    

    另一种方式,也许最简单的方法是在MongoDB 3.2中使用$filter operator new

    db.paths.aggregate([
        { "$project": { 
            "files": {
                "$filter": { 
                    "input": "$files", 
                    "as": "file",  
                    "cond": {
                        "$setIsSubset": [
                            { "$map": {
                                "input": { "$literal": [ "A" ] }, 
                                "as": "el", 
                                "in": "$$file.path"
                            }}, 
                            paths 
                        ]
                    }
                }
            }
        }}
    ])
    

    两个查询都会产生相同的结果:

    {
            "_id" : "3213dsadsa812321",
            "files" : [
                    {
                            "_id" : "99303",
                            "path" : "C:Filename04.txt"
                    }
            ]
    }
    

相关问题