【问题标题】:MongoDb get record based on dynamic keysMongoDb 根据动态键获取记录
【发布时间】:2020-07-25 23:03:29
【问题描述】:

我有一个动态架构。在下面的模式“ABC”中,“WQA”是动态键。我想获取来源为“sourceX”并且只想显示“CustomerId”和“code”的客户的记录。

我是 MongoDB 领域的初学者。我尝试了不同的解决方案,例如 How to query a dynamic key - mongodb schema design 但无法实现欲望输出。请在这里指导我。

{
 "_id" : ObjectId("5f0339e28fbb15b9f8a17181"), 
 "CustomerID" : "12345", 
 "ABC":[
   {
        "datetime" : ISODate("2020-06-13"), 
        "source" : "SourceX", 
        "code" : "ABC", 
   },
   {
       "datetime" : ISODate("2020-08-18"), 
       "source" : "SourceB", 
       "code" : "ABC",  
   }
  ],
"WQA":[
    {
        "datetime" : ISODate("2020-02-16"), 
        "source" : "SourceX", 
        "code" : "WQA", 
   },
   {
       "datetime" : ISODate("2020-03-16"), 
       "source" : "SourceY", 
       "code" : "WQA",  
   }
 ]
}

【问题讨论】:

    标签: database mongodb mongoose mongodb-query nosql


    【解决方案1】:

    以下聚合管道将能够实现您正在寻找的内容,但请注意,这不是一种对 mongo 非常友好的数据格式。 https://mongoplayground.net/p/ZRcbzEe1bkR

    db.collection.aggregate([
      {
        $project: {
          CustomerID: 1,
          entries: {
            $objectToArray: "$$ROOT"
          }
        }
      },
      {
        $unwind: "$entries"
      },
      {
        $unwind: "$entries.v"
      },
      {
        $match: {
          "entries.v.source": "SourceX"
        }
      },
      {
        $project: {
          _id: 0,
          CustomerID: 1,
          code: "$entries.v.code"
        }
      }
    ])
    

    如果可以,我强烈建议您将数据更改为只有一个数组,在这种情况下,您可以轻松地利用索引来加快查询速度。以下设置可以利用codes.source 上的索引来大大加快初始匹配速度。 https://mongoplayground.net/p/hBC1F-g9af1

    {
      "_id": ObjectId("5f0339e28fbb15b9f8a17181"),
      "CustomerID": "12345",
      "codes": [
        {
          "datetime": ISODate("2020-06-13"),
          "source": "SourceX",
          "code": "ABC"
        },
        {
          "datetime": ISODate("2020-08-18"),
          "source": "SourceB",
          "code": "ABC"
        },
        {
          "datetime": ISODate("2020-02-16"),
          "source": "SourceX",
          "code": "WQA"
        },
        {
          "datetime": ISODate("2020-03-16"),
          "source": "SourceY",
          "code": "WQA"
        }
      ]
    }
    

    然后您可以使用稍微修改的聚合管道来实现您想要的结果。

    db.collection.aggregate([
      {
        $match: {
          "codes.source": "SourceX"
        }
      },
      {
        $unwind: "$codes"
      },
      {
        $match: {
          "codes.source": "SourceX"
        }
      },
      {
        $project: {
          _id: 0,
          CustomerID: 1,
          code: "$codes.code"
        }
      }
    ])
    

    【讨论】:

      猜你喜欢
      • 2021-09-04
      • 2020-01-16
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多