sql >> Databáze >  >> NoSQL >> MongoDB

Agregace MongoDb Manipulace s daty – objekty do polí

Dotaz

  • jeho aktualizace agregace, i když nám potrubí neumožňuje používat fáze, jako je vyhledávání skupin atd., které se zde používají. (můžete použít $out a nahradit kolekci po nebo $merge nahradit dokumenty (podobně jako aktualizace))

  • první mapa

    • pro každou vlastnost (dokumentový člen vlastností) se dostane do pole
      [["trait_type": "type"] ["value": "Male"] ["display_type": null] ...]
    • redukovat na toto pole, aby se z nich vytvořil pouze 1 dokument
      {"type" "type","value" :"Male"} (má také malá písmena a "_")
  • Nyní vlastnosti jako

    "traits": [
      {
        "type": "type",
        "value": "Male"
      },
      {
        "type": "accessory",
        "value": "Mohawk"
      },
      {
        "type": "accessory",
        "value": "Earring"
      },
      {
        "type": "accessory",
        "value": "Frown"
      }
    ]
    
  • vyhledávání pomocí fiktivní kolekce [{}] (děláme to, abychom vytvořili skupinu uvnitř tohoto pole) je to jako trik, který nám umožňuje používat operátory fáze uvnitř 1 dokumentu

    • vyhledávací kanál se odvíjí a seskupuje podle typu
    "traits": [
      {
        "values": [
          "Mohawk",
          "Earring",
          "Frown"
        ],
        "type": "accessory"
      },
      {
        "values": [
          "Male"
        ],
        "type": "type"
      }
    ]
    
    • pak je to kořen pro nahrazení, který převezme hodnotu typu, udělá z něj název pole a hodnoty jako hodnotu (if size=1 removes the array)
  • Po vyhledání máme

    "traits": [
      {
        "accessory": [
          "Mohawk",
          "Earring",
          "Frown"
        ]
      },
      {
        "type": "Male"
      }
    ]
    
  • takže vše, co musíme udělat, je omezit tyto vlastnosti a sloučit objekty (klíče jsou stejně jedinečné, protože jsme je seskupili)

  • a dostaneme očekávaný výstup (alespoň si myslím, že je to v pořádku)

Testovací kód zde

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. Laravel - Mongodb [ jenssegers/laravel-mongodb ] - Tvůrce schémat

  2. Najít nejnovější a nejbližší příspěvky, limit 20

  3. Aktualizujte pole hodnotou jiného pole v dokumentu

  4. Redis set vs hash