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

グループごとの連結文字列

    「2ステップ」の操作として、集約フレームワークを使用してこれを行うことができます。これは、最初に $pushを介してアイテムを配列に蓄積することです。 $ group パイプラインを作成し、 $ concatを使用します $ reduce 最終的な投影で生成されたアレイについて:

    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"]
                }
              }
            }
          }
        }
      }}
    ])
    

    $ condも適用します ここでは、結果で空の文字列とコンマが連結されないようにするため、区切りリストのように見えます。

    参考までに、JIRAの問題があります SERVER-29339 $ reduceを要求します アキュムレータ式 として実装されます $ groupで直接使用できるようにする パイプラインステージ。すぐに発生する可能性は低いですが、理論的にはに置き換わるでしょう。 $ push 上記で、操作を単一のパイプラインステージにします。提案された構文のサンプルは、JIRAの問題に関するものです。

    $ reduceがない場合 (MongoDB 3.4が必要です)次に、カーソルを後処理します:

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

    次に、 mapReduce> 本当に必要な場合:

    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 } }
    )
    

    もちろん、特定の mapReduceに出力するのはどれですか _idの形式 およびvalue キーのセットとしてですが、基本的には出力です。

    []。concat.apply([]、values.map(...))を使用します mapReduce のため、「reducer」の出力は「区切り文字列」になる可能性があるためです。 大きな結果で段階的に機能するため、レデューサーの出力は別のパスで「入力」になる可能性があります。したがって、これが発生する可能性があることを期待し、それに応じて処理する必要があります。



    1. MongoDBは集約クエリのexecutionStatsを取得します

    2. $ lte$gteを使用した$fitlerネストされた配列

    3. キーを削除するにはどうすればよいですか?

    4. MongoDB $ hour