問題

私はこのような文書を持つデータベースを持っています:

 {
   _id: 123, 
   metrics: [{ 
               _id: ObjectID(…), 
               name: 'foo',
               steps: [1, 2, 3, …], 
               values: [10, 12, 13, …]
              },
              { 
               _id: ObjectID(…), 
               name: 'bar',
               steps: [1, 2, 3, …], 
               values: [1.2, 1.2, 1.3, …]
              },
             ]
}
 

今私の目的は、すべてのドキュメントを取得することですが、$mapはすべての配列エントリをname属性に、他のフィールドを破棄します。私はこれを次のようにすることができると思った:

 pipeline = [{'$project': {'metrics': {'$map': {'input': '$metrics', 'in': '$this.name'}]
results = client.db.runs.aggregate(pipeline)
 

しかし、結果には、要求されたフィールドnameが存在しなかったかのように、各配列エントリ({'metrics': [None, None, None, …]})のNone値しかありません。しかし、そうです。私はまた、idフィールドで試してみましたが、役に立たなかった。私はフィールドがそこにあるデータを調べることができます。私はここで間違っていることを理解できません。

  ベストアンサー

$ map の内部では、as を使用して、metrics の単一の文書を表す一時変数を定義し、その変数を in の部分で参照することができます。

 db.col.aggregate([{'$project': {'metrics': {'$map': {'input': '$metrics', as: 'metric', 'in': '$$metric.name' } } } }])
 

または、一時変数 this を直接参照することもできます。

 db.col.aggregate([{'$project': {'metrics': {'$map': {'input': '$metrics', 'in': '$$this.name' } } } }])
 

事は、単一ドル記号を使用するたびに、現在のパイプライン段階で処理されているドキュメントで定義されているフィールドを参照することです。さらに、ダブルドル記号を使用して、$map$filterなどの演算子によって定義できる変数を参照できます。

次の文書については、初期コードを試すことができます。

 {
    _id: 123, 
    this: { name: "x" },
    metrics: [{ }, { } ]
}
 

2つのメトリックがあるので、2つのx値を持つ配列を取得しますが、すべての反復は同じthis.x値を参照します。

 { "_id" : 123, "metrics" : [ "x", "x" ] }
 

  同じタグがついた質問を見る

pythonarraysmongodbaggregation-framework