sql >> データベース >  >> NoSQL >> MongoDB

MongoDbアグリゲーションデータ操作-オブジェクトから配列へ

    クエリ

    • ここで使用されているグループルックアップなどのステージをパイプラインで使用できない場合でも、集約が更新されます。 ($outを使用できます または$mergeの後にコレクションを置き換えます ドキュメントを置き換える(更新と同様))

    • 最初の地図

      • トレイト(トレイトのドキュメントメンバー)ごとに、配列になります
        [["trait_type": "type"] ["value": "Male"] ["display_type": null] ...]
      • その配列を縮小して、1つのドキュメントのみを構成します
        {"type" "type","value" :"Male"} (小文字と「_」も使用します)
    • 今、そのような特徴を持っています

      "traits": [
        {
          "type": "type",
          "value": "Male"
        },
        {
          "type": "accessory",
          "value": "Mohawk"
        },
        {
          "type": "accessory",
          "value": "Earring"
        },
        {
          "type": "accessory",
          "value": "Frown"
        }
      ]
      
    • ダミーコレクションを使用したルックアップ[{}] (その配列内にグループを作成するためにこれを行います)これは、1つのドキュメント内でステージ演算子を使用できるようにするトリックのようなものです

      • ルックアップパイプラインが巻き戻され、タイプ別にグループ化されます
      "traits": [
        {
          "values": [
            "Mohawk",
            "Earring",
            "Frown"
          ],
          "type": "accessory"
        },
        {
          "values": [
            "Male"
          ],
          "type": "type"
        }
      ]
      
      • 次に、その置換ルートでtypeの値を取得し、フィールド名と値を値(if size=1 removes the array)
    • ルックアップ後、

      "traits": [
        {
          "accessory": [
            "Mohawk",
            "Earring",
            "Frown"
          ]
        },
        {
          "type": "Male"
        }
      ]
      
    • したがって、私たちがしなければならないのは、その特性を減らしてオブジェクトをマージすることだけです(キーはそれらによってグループ化されているため、とにかく一意です)

    • 期待どおりの出力が得られます(少なくとも大丈夫だと思います)

    ここでコードをテスト

    db.collection.aggregate([
      {
        "$set": {
          "traits": {
            "$map": {
              "input": "$traits",
              "as": "t",
              "in": {
                "$reduce": {
                  "input": {
                    "$map": {
                      "input": {
                        "$objectToArray": "$$t"
                      },
                      "as": "m",
                      "in": [
                        "$$m.k",
                        "$$m.v"
                      ]
                    }
                  },
                  "initialValue": {},
                  "in": {
                    "$let": {
                      "vars": {
                        "type_value": "$$value",
                        "ta": "$$this"
                      },
                      "in": {
                        "$let": {
                          "vars": {
                            "key": {
                              "$arrayElemAt": [
                                "$$ta",
                                0
                              ]
                            },
                            "value": {
                              "$arrayElemAt": [
                                "$$ta",
                                1
                              ]
                            }
                          },
                          "in": {
                            "$switch": {
                              "branches": [
                                {
                                  "case": {
                                    "$eq": [
                                      "$$key",
                                      "value"
                                    ]
                                  },
                                  "then": {
                                    "$mergeObjects": [
                                      "$$type_value",
                                      {
                                        "value": "$$value"
                                      }
                                    ]
                                  }
                                },
                                {
                                  "case": {
                                    "$eq": [
                                      "$$key",
                                      "trait_type"
                                    ]
                                  },
                                  "then": {
                                    "$mergeObjects": [
                                      "$$type_value",
                                      {
                                        "type": {
                                          "$replaceAll": {
                                            "input": {
                                              "$toLower": "$$value"
                                            },
                                            "find": " ",
                                            "replacement": "_"
                                          }
                                        }
                                      }
                                    ]
                                  }
                                }
                              ],
                              "default": "$$type_value"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      {
        "$lookup": {
          "from": "dummy",
          "let": {
            "traits": "$traits"
          },
          "pipeline": [
            {
              "$set": {
                "traits": "$$traits"
              }
            },
            {
              "$unwind": {
                "path": "$traits"
              }
            },
            {
              "$replaceRoot": {
                "newRoot": "$traits"
              }
            },
            {
              "$group": {
                "_id": "$type",
                "values": {
                  "$push": "$value"
                }
              }
            },
            {
              "$set": {
                "type": "$_id"
              }
            },
            {
              "$project": {
                "_id": 0
              }
            },
            {
              "$replaceRoot": {
                "newRoot": {
                  "$cond": [
                    {
                      "$eq": [
                        {
                          "$size": "$values"
                        },
                        1
                      ]
                    },
                    {
                      "$arrayToObject": {
                        "$let": {
                          "vars": {
                            "pair": [
                              [
                                "$type",
                                {
                                  "$arrayElemAt": [
                                    "$values",
                                    0
                                  ]
                                }
                              ]
                            ]
                          },
                          "in": "$$pair"
                        }
                      }
                    },
                    {
                      "$arrayToObject": {
                        "$let": {
                          "vars": {
                            "pair": [
                              [
                                "$type",
                                "$values"
                              ]
                            ]
                          },
                          "in": "$$pair"
                        }
                      }
                    }
                  ]
                }
              }
            }
          ],
          "as": "traits"
        }
      },
      {
        "$set": {
          "traits": {
            "$mergeObjects": "$traits"
          }
        }
      }
    ])
    



    1. プロアクティブなMongoDBモニタリング(Developer Studio / Advisorsの角度)

    2. Spring Data Mongodb:ドキュメントの更新

    3. アクティビティのタイムラインをmongodbのどこに配置するか、ユーザーに埋め込むか、個別に配置する必要がありますか?

    4. HomebrewでMongoDBをインストールする