2016-09-18 2 views
0

私がここでやろうとしているのは、配列として複数のサブ文書を照会してマージすることです。私は、集約の枠組みが行く方法だと思うが、私はそれを正確に得ることはできない。複数のサブ文書を集計投影の配列として結合するMongoDB

{ 
    "_id": ObjectId("57dc5c2b7463d336ec3fff8c"), 
    "username": "Bob", 
    "fullname": "Bobby", 
    "activities": 
     { "visits" : [ 
     { 
      "_id": ObjectId("57dc674e4208b12fd4a52a3d"), 
      "date": ISODate("2016-09-18T08:00:00.000Z"), 
      "location" : "Jakarta", 
     }, 
     { 
      "_id": ObjectId("57dd3795c13c5e2b7484ea4b"), 
      "date": ISODate("2016-09-17T08:00:00.000Z"), 
      "location" : "Denpasar", 
     } 
     ], 
     "purchases" : [ 
     { 
      "_id": ObjectId("57dc4769c0f09317282b3f92"), 
      "date": ISODate("2016-09-17T07:30:00.000Z"), 
      "product_name" : "Shirt", 
      "price": 125000 
     },{ 
      "_id": ObjectId("57dbfdc6be9dcf1e7c4a1751"), 
      "date": ISODate("2016-09-18T08:30:00.000Z"), 
      "product_name" : "Shoes", 
      "price": 150000 
     } 
     ]}, 
    } 
} 

そして、ここでは私がをしたいと凝集に達成しようとすること文書が、私は日付によってそれらをsortできる条件で、これである:ここでは

は私のコレクションは訪問者と呼ばれますlimitskipを使用してください。

{ 
    "_id": ObjectId("57dc5c2b7463d336ec3fff8c"), 
    "activities": [ 
    { 
     "activity_type": "purchases", 
     "_id": ObjectId("57dbfdc6be9dcf1e7c4a1751"), 
     "date": ISODate("2016-09-18T08:30:00.000Z"), 
     "product_name" : "Shoes", 
     "price": 150000 
    },{ 
     "activity_type": "visits", 
     "visits_id": ObjectId("57dc674e4208b12fd4a52a3d"), 
     "date": ISODate("2016-09-18T08:00:00.000Z"), 
     "location" : "Jakarta", 
    },{ 
     "activity_type": "visits", 
     "visits_id": ObjectId("57dd3795c13c5e2b7484ea4b"), 
     "date": ISODate("2016-09-17T08:00:00.000Z"), 
     "location" : "Denpasar", 
    },{ 
     "activity_type": "purchases", 
     "date": ISODate("2016-09-17T07:30:00.000Z"), 
     "product_name" : "Shirt", 
     "price": 125000 
    }] 
} 

私はこの集約

db.visitors.aggregate([{ 
    $match: { _id: ObjectId("57dc5c2b7463d336ec3fff8c") } }, 
    { 
     $group: { 
      _id: "$_id", 
      visits: { 
      "$addToSet": "$activities.visits" 
      }, 
      purchases: { 
      "$addToSet": "$activities.purchases" 
      } 
     } 
    }]) 

でこれをやろうとしてきた。しかし、私は私が望む正確に何を得ることはありません、それは代わりに自分のタイプでわずかグループにそれらをした、と私は」することができますt skiplimitを使用しても(ちょうどスキップし、訪問者の数を制限すると思われる)。

{ 
    "_id": ObjectId("57dc5c2b7463d336ec3fff8c"), 
    "visits": [ 
     [ 
     { 
      "_id": ObjectId("57dc674e4208b12fd4a52a3d"), 
      "date": ISODate("2016-09-18T08:00:00.000Z"), 
      "location" : "Jakarta", 
     }, 
     { 
      "_id": ObjectId("57dd3795c13c5e2b7484ea4b"), 
      "date": ISODate("2016-09-17T08:00:00.000Z"), 
      "location" : "Denpasar", 
     } 
     ] 
    ], 
    "news": [ 
     [ 
     { 
      "_id": ObjectId("57dc4769c0f09317282b3f92"), 
      "date": ISODate("2016-09-17T07:30:00.000Z"), 
      "product_name" : "Shirt", 
      "price": 125000 
     },{ 
      "_id": ObjectId("57dbfdc6be9dcf1e7c4a1751"), 
      "date": ISODate("2016-09-18T08:30:00.000Z"), 
      "product_name" : "Shoes", 
      "price": 150000 
     } 
     ] 
    ] 
} 

、私はこのunwindで別の投影しようとした、

db.visitors.aggregate([ 
    { $match: { _id: ObjectId("57dc5c2b7463d336ec3fff8c") } }, 
    { $unwind: '$activities.visits' }, 
    { $unwind: '$activities.purchases' }, 
    { $project: { 
     _id: 0, 
     //visits 
     "visits_id": "$activities.visits._id", 
     "visits_date": "$activities.visits.date", 
     "visits_location" : "$activities.visits.location" 
     //purchases 
     "purchases_id": "$activities.purchases._id", 
     "purchases_date": "$activities.purchases.date", 
     "purchases_product_name": "$activities.purchases.product_name", 
     "purchases_price": "$activities.purchases.price", 
    } 
    } 
]) 
    .skip(0) 
    .limit(2) 

が、各インデックス

{ 
    "_id": ObjectId("57dc5c2b7463d336ec3fff8c"), 
    "activities": [ 
    { 
     "purchases_id": ObjectId("57dbfdc6be9dcf1e7c4a1751"), 
     "purchases_date": ISODate("2016-09-18T08:30:00.000Z"), 
     "purchases_product_name" : "Shoes", 
     "purchases_price": 150000 
     "visits_id": ObjectId("57dc674e4208b12fd4a52a3d"), 
     "visits_date": ISODate("2016-09-18T08:00:00.000Z"), 
     "visits_location" : "Jakarta", 
    },{ 
     "purchases_id": ObjectId("57dc4769c0f09317282b3f92"), 
     "purchases_date": ISODate("2016-09-17T07:30:00.000Z"), 
     "purchases_product_name" : "Shirt", 
     "purchases_price": 125000 
     "visits_id": ObjectId("57dd3795c13c5e2b7484ea4b"), 
     "visits_date": ISODate("2016-09-17T08:00:00.000Z"), 
     "visits_location" : "Denpasar", 
    }] 
} 

で異なるタイプの文書をマージするようでは行うことが可能ですこれは私の現在の文書ですか?ドキュメント構造を変更する必要がありますか?

アップデートは、私は、アレイ内の私のサブドキュメントのそれぞれでactivity_typeを追加し、配列として複数の配列をマージし、そして配列を制限し、スキップする$sliceを使用する$setUnionを使用してこの問題を解決することになった

を解決しました。私は知りませんが、あなたが、配列の各要素にactivity_typeフィールドを追加した場合、1つのaggregation段階で$setUnionを使用して簡単になります$setUnionがすでに自動的に

db.visitors.aggregate([ 
{ 
    $project: { 
     activities: { 
      $setUnion: ['$activities.visits', '$activities.purchases'], 
     } 
    } 
}, 
{ 
    $project:{ 
     activites: { 
      $slice: ["$activities", 0, 2] 
     } 
    } 
} 
]) 
+0

'$ slice'はスキップとリミットとして機能しますが、問題は解決しません。一方、' $ setUnion'は私が探していたものです – fadeltd

答えて

1

それをソートするようだ:

db.visitors.aggregate([ 
    { 
     $project: { 
      activities: { 
       $setUnion: ['$activities.visits', '$activities.purchases'] 
      } 
     } 
    } 
]) 

この場合、配列を連結してそのタイプのアクティビティ配列にします。あなたの質問の他の部分については

sortskiplimit、あなたが必要な文書を$matchする必要がありますので、各ドキュメントではなく、サブ文書で動作する集約段階あり、$unwind結果前からactivities配列sortskiplimitの演算子をすべて使用できます。

+1

これは結果から重複を除外します。 – styvane

+1

@Styvane 'visits'と' purchases'にはどちらも '_id'フィールドがあり、重複はありません。私は彼に両方のための 'activity_type'フィールドを追加するように依頼しました – TomG

+0

あなたは正しいです。私はそれに気付かなかった。 – styvane

関連する問題