2017-09-19 4 views
1

MongoDB集約パイプライン内にプロジェクトを作成しようとしているサンプル文書があります。私は、おおよそ次のようになり、単一の文書でテストしています:文書の各配列要素に式を適用する

{ 
    "_id" : "", 
    "title" : "Questions", 
    "sortIndex" : 0, 
    "topics" : [ 
     { 
      "_id" : "", 
      "title" : "Creating a Question", 
      "sortIndex" : 1, 
      "thumbnail" : "CreatingAQuestion.jpg", 
      "seenBy" : [ "user101", "user202" ], 
      "pages" : [ 
       { 
        "visual" : "SelectPlanets.gif", 
        "text" : "Some Markdown" 
       } 
      ] 
     }, 
     { 
      "_id" : "", 
      "title" : "Deleting a Question", 
      "sortIndex" : 0, 
      "thumbnail" : "DeletingAQuestion.jpg", 
      "seenBy" : [ "user101" ], 
      "pages" : [ 
       { 
        "visual" : "SelectCard.gif", 
        "text" : "Some Markdown" 
       } 
      ] 
     } 
    ] 
} 

私が取得しようとしている出力は、これらの線に沿って何かである:

{ 
    "_id" : "", 
    "title" : "Questions", 
    "topics" : [ 
     { 
      "title" : "Creating a Question", 
      "thumbnail" : "CreatingAQuestion.jpg", 
      "seen" : true 
     }, 
     { 
      "title" : "Deleting a Question", 
      "thumbnail" : "DeletingAQuestion.jpg", 
      "seen" : false 
     } 
    ] 
} 

私は苦労しています。具体的ビットseenフラグです。

私が読んだdocsた状態:

投または埋め込まれた文書内のフィールドをリセット/追加...

...それともネストできるフィールド:

contact: { address: { country: <1 or 0 or expression> } }

私は表現を使いたいと私は次のことに注意しました:

フィールドをネストするとき、埋め込みドキュメント内のドット表記を使用してフィールドを指定することはできません。連絡先:{ "address.country": <1 or 0 or expression> }は無効です。

私はどのように式内のサブドキュメントフィールドを参照するかを考えています。引用符ではのドット表記を使用することはできませんが、私はネストされた表記でも動作しないようです。ここで私はこれまで持っているものだ:

db 
    .getCollection('chapters') 
    .aggregate([ 
     { 
      $project: { 
       title: 1, 
       topics: { 
        title: 1, 
        thumbnail: 1, 
        publishedAt: 1, 
        test: "$seenBy", 
        seen: { $in: ["user202", "$seenBy"] }, 
       } 
      } 
     } 
    ]) 

をだから私はハード今の私のクエリへuser202をコード化され、そして2つのドキュメントをを見ると期待しました。私はまた、testフィールドにサブ文書からseenByフィールドをマッピングしました。これが何を生産することである:

{ 
    "_id" : "", 
    "title" : "Questions", 
    "topics" : [ 
     { 
      "title" : "Creating a Question", 
      "thumbnail" : "CreatingAQuestion.jpg", 
      "test" : [ 
       "user101", 
       "user202" 
      ], 
      "seen" : true 
     }, 
     { 
      "title" : "Deleting a Question", 
      "thumbnail" : "DeletingAQuestion.jpg", 
      "test" : [ 
       "user101", 
       "user202" 
      ], 
      "seen" : true 
     } 
    ] 
} 

だから、明らかに私の testフィールドが第一文書からのデータが含まれているため、「$ seenBy」正しいトピックにアクセスしていません。

最終的に私の質問は、どのようにサブ文書内のseenByフィールドにアクセスできますか?現在のサブ文書を参照して、式を作成できますか?

注:これは複数の$project$unwindで動作しますが、少し圧縮してみてみたかったです。

答えて

2

実際には$mapを使用する必要があります。 MongoDB 3.2以降では、配列を投影で単に指定するだけで、現在の要素にローカライズされた値が必要な場合には実際には切り取られません。それはあなたが必要なものであり、$mapが提供するものです。

db.getCollection('chapters').aggregate([ 
    { $project: { 
    title: 1, 
    topics: { 
     $map: { 
     input: "$topics", 
     as: "t", 
     in: { 
      title: "$$t.title", 
      thumbnail: "$$t.thumbnail", 
      publishedAt: "$$t.publishedAt", 
      test: "$$t.seenBy", 
      seen: { $in: ["user202", "$$t.seenBy"] }, 
     } 
     } 
    }} 
]) 

財産として"seenBy"の現在の値が式によってテストされている各要素のようにします。 $mapが不可能な場合、実際には "全体"配列のみを指定することができます。実際にあなたがここでテストしたいものではありません。

+0

以前は '$ map'を使用していなかったことにとても感謝していますが、あなたがそれについて考えるときには使い方に合っていると完全に理解しています。私は、私が望むことができるはずのように聞こえてきたので、ドキュメントが間違った道を導いたと思う。 – Ian

関連する問題