2017-06-30 10 views
1

PHPを使用してmongodbのカウントについて知りたいだけです。この場合、私は、文書は次のようになります:配列内のフィールドのすべてのドキュメントを集計します。

{ 
"_id": 1, 
"item" : [ 
{ "name": "foo", 
"price": 1000 
}, 
{ "name": "bar", 
"price": 500 
} 
] 
} 

{ 
"_id": 2, 
"item" : [ 
{ "name": "foo", 
"price": 1000 
} 
] 
} 

私はこのような次のコードを使用していました:

$connection = new MongoClient(); 
$db = $connection->shop; 
$collection = $db->sales; 
$pipe = array(array('$unwind'=>'$item'), 
array('$group'=>array('_id'=>array('_id'=>'1','result'=>array('$sum'=>'$item.price'))))); 
$total = $collection->aggregateCursor($pipe); 
foreach ($total as $dc){ 
$total_price = $dc['result']; 
} 
echo "<b>Result of all this customer : </b>".$total_price."<br>"; 
そのコードの結果が

は、すべての文書の結果などのように見えますが:他の側で

Result of all this customer : 2500 

私が望むように、結果はIDごとにカウントされていないすべて私が持っていた文書のカウントのために。そのコードの何が間違っていますか?

私は、この例の結果を願っています:

Result of all this customer : 1500 

誰かが私を助けてください...

私は多分それは同じ悩みを持っていた人を助けます、見つかった以下の答え。

$connection = new MongoClient(); 
    $db = $connection->shop; 
    $collection = $db->sales; 
    $pipe = array(array('$unwind'=>'$item'),array('$match'=>array('_id'=>'1')), array('$group'=>array('_id'=>array('_id'=>'1','result'=>array('$sum'=>'$item.price'))))); 
    $total = $collection->aggregateCursor($pipe); 
    foreach ($total as $dc){ 
    $total_price = $dc['result']; 
    } 
    echo "<b>Result of all this customer : </b>".$total_price."<br>"; 

idをソートするための$ matchを追加しました。このクエリは、ターゲットIDを持つ埋め込みドキュメントのみをチェックします。

+1

単純に1つのパイプラインステージ。最新のPHPを使用して、[[''グループ=> ['_id' => NULL、 'total_price' => ['$ sum' => ['$ sum' => '$ item.price']]]]] 'ここでは 'array()'の代わりに '[]'を使っています。 –

+0

なぜあなたは$ unwindを取って$ groupに直接行っていないのですか? @NeilLunn – Unknown

+0

あなたがそれを必要とせず、物事を遅くするので、かなり。最新のMongoDBリリースでは '$ sum'を配列の引数とともに適用できます。 '' $ item.price''は、 '' price''フィールド値の "only"の配列を返します。その配列の合計を得るには$ sumに渡します。そして、 '$ sum'が再び使われます実際の '$ group'ステートメントのために" accumulate "します。したがって '$ sum'の二重使用。私は他のところでこの質問に答えてきたことを知っているので、私はそれを探しています。 –

答えて

0

あなたが実際にグループ化のための配列項目と「アキュムレータ」の両方に$sumを使用することができますので、あなたはここでしか単一$groupパイプラインステージを必要とする:

$result = $collection->aggregate([ 
    [ '$group' => [ 
    '_id' => null, 
    'total_price' => [ '$sum' => [ '$sum' => '$item.price' ] ] 
    ]] 
]) 

たはず$unwindを使用するよりも多くの方が効率的ですあなたが実際にそれを必要としないときは、避けてください。

$unwindを使用して、古いやり方では、実際にフィールドを指す:ここ

$result = $collection->aggregate([ 
    [ '$unwind' => '$item' ], 
    [ '$group' => [ 
    '_id' => null, 
    'total_price' => [ '$sum' => '$item.price' ] 
    ]] 
]) 
+0

申し訳ありませんが、まだ動作しません。空白(出力なし)。この問題を解決する方法はありますか?そして、私は、各文書のグループだけを取得するために、いくつかのIDを実現させていないということをあなたが何を意味するのか分かりません。 – Unknown

+0

私の記事を見て、私は答えを見つけました。私を助けてくれてありがとう。皆を助けるためにそれを保つ! – Unknown

0

は集合体です。マッチステージを削除すると、すべてのユーザーに合計が与えられます。

> db.product.aggregate(
... [ 
...  { 
...   $match: {'_id':{ '$eq': 1}} 
...  }, 
...  { 
...   $unwind: '$item' 
...  }, 
...  { 
...   $group : { 
...   _id : '$_id', 
...   totalPrice: { $sum: '$item.price' }, 
...   } 
...  } 
... ] 
...) 
{ "_id" : 1, "totalPrice" : 1500 } 
関連する問題