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

Concat String podle skupiny

Můžete to udělat s agregačním rámcem jako „dvoukrokovou“ operaci. Což je nejprve shromáždit položky do pole prostřednictvím $push v rámci $group potrubí a poté použít $concat s $reduce na vyrobeném poli ve finální projekci:

db.collection.aggregate([
  { "$group": {
    "_id": "$tag_id",
    "client_id": { "$push": "$client_id" }
  }},
  { "$addFields": {
    "client_id": {
      "$reduce": {
        "input": "$client_id",
        "initialValue": "",
        "in": {
          "$cond": {
            "if": { "$eq": [ "$$value", "" ] },
            "then": "$$this",
            "else": {
              "$concat": ["$$value", ",", "$$this"]
            }
          }
        }
      }
    }
  }}
])

Aplikujeme také $cond zde, abyste se vyhnuli zřetězení prázdného řetězce čárkou ve výsledcích, takže to vypadá spíše jako seznam s oddělovači.

FYI Vyskytl se problém JIRA SERVER-29339 který požaduje $reduce být implementován jako výraz akumulátoru umožnit jeho použití přímo v $group fáze potrubí. Není pravděpodobné, že by se to stalo v dohledné době, ale teoreticky by to nahradilo $push ve výše uvedeném a učinit z operace jedinou etapu potrubí. Ukázka navrhované syntaxe se týká problému JIRA.

Pokud nemáte $reduce (vyžaduje MongoDB 3.4), poté stačí zpracovat kurzor:

db.collection.aggregate([
  { "$group": {
    "_id": "$tag_id",
    "client_id": { "$push": "$client_id" }
  }},
]).map( doc =>
  Object.assign(
    doc,
   { "client_id": doc.client_id.join(",") }
  )
)

Což pak vede k další alternativě, jak to udělat pomocí mapReduce pokud opravdu musíte:

db.collection.mapReduce(
  function() {
    emit(this.tag_id,this.client_id);
  },
  function(key,values) {
    return [].concat.apply([],values.map(v => v.split(","))).join(",");
  },
  { "out": { "inline": 1 } }
)

Což je samozřejmě výstup ve specifickém mapReduce ve tvaru _id a value jako sadu klíčů, ale je to v podstatě výstup.

Používáme [].concat.apply([],values.map(...)) protože výstupem „reduktoru“ může být „oddělený řetězec“, protože mapReduce pracuje postupně s velkými výsledky, a proto se výstup reduktoru může stát "vstupem" při dalším průchodu. Musíme tedy očekávat, že se to může stát, a podle toho s tím zacházet.



  1. Stránkování Redis Hash

  2. Proč potřebujeme, jaké výhody používat mangustu

  3. Sloučit dvě pole pole v mongoDB

  4. Jak odstranit kolekci Mongodb pomocí názvu kolekce v c#