【问题标题】:Mongodb comparing object arrays keysMongodb比较对象数组键
【发布时间】:2016-04-03 12:25:48
【问题描述】:

我的 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: "99303" 应该返回 db 中,因为它与 var 对象数组 _id: "4" 匹配。

预期结果:

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

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

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

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您需要另一个仅包含映射路径的数组,并且可以使用 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 }})
    

    【讨论】:

      【解决方案2】:

      使用.aggregate() 方法。

      首先,您需要使用.map() 方法返回一个“路径”数组。

      > 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 运算符返回一组子文档,其中“路径”位于“dynFiles”中。要检查给定的“路径”是否在“dynFiles”中,请在$cond 表达式中使用$setIsSubset 运算符。您需要$setIsSubset 的原因是您不能在$cond 表达式中使用$in 运算符。当然$setIsSubset 运算符需要两个数组作为参数,您需要使用$map 运算符返回一个元素数组。当然,$literal 运算符允许您将文字数组分配给$map 中的“输入”。此外,您还需要在这里使用$setDifference 从数组中过滤掉所有false,只要被过滤的数据是“唯一的”就可以了。

      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 运算符 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"
                      }
              ]
      }
      

      【讨论】:

        猜你喜欢
        • 2021-06-02
        • 2019-07-02
        • 1970-01-01
        • 1970-01-01
        • 2020-04-10
        • 2018-02-06
        • 1970-01-01
        • 2019-06-28
        相关资源
        最近更新 更多