sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDb Aggregation Datamanipulation - Objekt till Arrayer

Fråga

  • det är en aggregeringsuppdatering även om pipeline inte tillåter oss att använda steg som gruppsökning etc som här används. (du kan använda $out och ersätt samlingen efter eller $merge för att ersätta dokument (liknar uppdatering))

  • första kartan

    • för varje egenskap (dokumentmedlem av egenskaper) gör den den till en array
      [["trait_type": "type"] ["value": "Male"] ["display_type": null] ...]
    • minska på den arrayen för att konstruera endast 1 dokument från dem
      {"type" "type","value" :"Male"} (gör det också gemener och "_")
  • Nu egenskaper är det som

    "traits": [
      {
        "type": "type",
        "value": "Male"
      },
      {
        "type": "accessory",
        "value": "Mohawk"
      },
      {
        "type": "accessory",
        "value": "Earring"
      },
      {
        "type": "accessory",
        "value": "Frown"
      }
    ]
    
  • slå upp med dummy-samlingen [{}] (vi gör det för att skapa en grupp inuti den arrayen) det är som ett trick som låter oss använda scenoperatorer i ett dokument

    • uppslagspipeline avvecklas och grupperas efter typ
    "traits": [
      {
        "values": [
          "Mohawk",
          "Earring",
          "Frown"
        ],
        "type": "accessory"
      },
      {
        "values": [
          "Male"
        ],
        "type": "type"
      }
    ]
    
    • då är det en ersättningsrot att ta värdet av typ, göra det till fältnamnet och värdena som värdet (if size=1 removes the array)
  • Efter uppslag har vi

    "traits": [
      {
        "accessory": [
          "Mohawk",
          "Earring",
          "Frown"
        ]
      },
      {
        "type": "Male"
      }
    ]
    
  • så allt vi behöver göra är att minska dessa egenskaper och slå samman objekten (nycklarna är unika ändå eftersom vi grupperade efter dem)

  • och vi får det förväntade resultatet (åtminstone jag tror att det är okej)

Testkod här

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. Hur man hämtar bildfiler från mongodb till html-sida

  2. Fick duplicerad data när du prenumererade flera gånger

  3. Behöver göra .toArray() för att få utdata från mongodb .find() på nyckelnamn inte värde

  4. MongoDB Java Driver Update Sub-Document