【问题标题】:Projection in MongoDB based on ConditionsMongoDB中基于条件的投影
【发布时间】:2017-04-19 20:18:03
【问题描述】:

我在 c# 中的文档结构:

 public class HashTableDocument : Model
    {
        public int Id { get; set; }
        public Dictionary<string, HashSet<int>> items= new Dictionary<string, HashSet<int>>();
    }

在蒙古:

{
    "_id" : 218,
    "items" : {
        "1" : [ 
            52711, 
            201610, 

        ],
        "2" : [ 
            246421, 
            390200
        ],
        "3" : [ 
            105628, 
            768519
        ],
        "26" : [ 
            17435, 
            22252, 
            61389, 
            65184, 
            72859, 
            81421, 
            931469, 
            933505, 
            938377, 
            959836
        ],
        "27" : [ 
            26917, 
            38706, 
            53862, 
            111816, 
            827294, 
            858348, 
            870334
        ]
    }
}

我希望能够将任何整数列表 ('x') 传递给 Mongo。如果值包含给定列表('x')中的任何整数,则仅对那些键值对进行投影。

例如,在上面的文档中。如果我将 List = { 52711, 105628, 17435, 81421} 传递给 Mongo 那么 它应该返回

{
    "_id" : 218,
    "items" : {
        "1" : [ 
            52711, 
            201610, 

        ],
        "3" : [ 
            105628, 
            768519
        ],
        "26" : [ 
            17435, 
            22252, 
            61389, 
            65184, 
            72859, 
            81421, 
            931469, 
            933505, 
            938377, 
            959836
        ],
     }
}

因为每个键的值在其列表中都包含至少一个元素

【问题讨论】:

    标签: c# mongodb mongodb-query aggregation-framework projection


    【解决方案1】:

    我不知道 C# 语法,但这里是使用聚合框架的方法。请注意,这使用了 3.4.4 版中引入的 $objectToArray 表达式。

    > db.test.aggregate([{
      $project: {
        x: {
          $filter: {
            input: {$objectToArray: "$items"},
            cond: {
              $gt: [
                {
                  $size: {
                    $filter: {
                      input: "$$this.v",
                      as: "int",
                      cond: {$in: ["$$int", [52711, 105628, 17435, 81421]]}
                    }
                  }
                },
                0
              ]
            }
          }
        }
      }
    }])
    {
      "result": [
        {
          "_id": 218,
          "items": [
            {
              "k": "1",
              "v": [
                52711,
                201610
              ]
            },
            {
              "k": "3",
              "v": [
                105628,
                768519
              ]
            },
            {
              "k": "26",
              "v": [
                17435,
                22252,
                61389,
                65184,
                72859,
                81421,
                931469,
                933505,
                938377,
                959836
              ]
            }
          ]
        }
      ],
      "ok": 1
    }
    

    但是,当您拥有像您这样的结构时,进行这样的计算通常并不容易。此聚合不能使用任何索引来限制其搜索。您是否考虑过改用以下架构?

    {
      "_id": 218,
      "items": [
        {k: "1", v: [52711, 201610]},
        {k: "2", v: [246421, 390200]},
        {k: "3", v: [105628, 768519]},
        {k: "26", v: [17435, 22252, 61389, 65184, 72859, 81421, 931469, 933505, 938377, 959836]},
        {k: "27", v: [26917, 38706, 53862, 111816, 827294, 858348, 870334]},
      ]
    }
    

    那么你的问题就变得简单多了,你可以改为:

    db.test.aggregate([
      {$match: {"items.v": {$in: [52711, 105628, 17435, 81421]}}},
      {
        $project: {
          items: {
            $filter: {
              input: "$items",
              cond: {
                $size: {
                  $setIntersection:
                      [[52711, 105628, 17435, 81421], "$$this.v"]
                }
              }
            }
          }
        }
      }
    ])
    

    如果您在“items.v”字段上创建了索引,则初始 $match 阶段可以利用该索引进行更高效的查询。

    【讨论】:

      猜你喜欢
      • 2020-11-21
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多