2016-03-31 10 views
3

私はmongoDBでこのクエリを実行し、結果が得られます。しかし今、私はそれをjavaで使用しようとしています。Javaで.group()を実行する方法

var red = function(doc, out) { 
out.count_order++; 
out.sum_qty += doc.quantity; 
out.sum_base_price += doc.extendedprice; 
out.sum_disc_price += doc.extendedprice * (1 - doc.discount); 
out.sum_charge += doc.extendedprice * (1 - doc.discount) * (1 + doc.tax); 
out.avg_disc += doc.discount; 
}; 

var avg = function(out) { 
out.avg_qty = out.sum_qty/out.count_order; 
out.avg_price = out.sum_base_price/out.count_order; 
out.avg_disc = out.avg_disc/out.count_order; 
}; 

db.lineitems.group({ 
key : { returnflag : true, linestatus : true}, 
cond : { "shipdate" : {$lte: 19980801}}, 
initial: { count_order : 0, sum_qty : 0, sum_base_price : 0, sum_disc_price : 0, 
sum_charge : 0, avg_disc : 0}, 
reduce : red, 
finalize : avg 
}); 

そして今、私はJavaでそれを使用していますが、私は平均機能を使用する方法がわからない方法:

これは、MongoDBのでクエリです。

String avg = "var avg = function(out) {" 
      + "out.avg_qty = out.sum_qty/out.count_order;" 
      + "out.avg_price = out.sum_base_price/out.count_order;" 
      + "out.avg_disc = out.avg_disc/out.count_order;};"; 

    String reduce = "function(doc, out) {" 
      + "out.count_order++;" 
      + "out.sum_qty += doc.quantity;" 
      + "out.sum_base_price += doc.extendedprice;" 
      + "out.sum_disc_price += doc.extendedprice * (1 - doc.discount);" 
      + "out.sum_charge += doc.extendedprice * (1 - doc.discount) * (1 + doc.tax);" 
      + "out.avg_disc += doc.discount;};"; 

    String finalize = "function(out) {" 
      + "out.avg_qty = out.sum_qty/out.count_order;" 
      + "out.avg_price = out.sum_base_price/out.count_order;" 
      + "out.avg_disc = out.avg_disc/out.count_order;};"; 

    MapReduceIterable<Document> iterable = collection.mapReduce(**????**, reduce).finalizeFunction(finalize); 

どうすればこの機能を使用できますか?

答えて

1

もちろん、実際に存在していた集約フレームワークの前に古い実装である​​メソッドを呼び出すよりも、このためのaggreationフレームワークを使用したほうが良いでしょう。

あろうシェルに適用される論理:

db.lineitems.aggregate([ 
    { "$match": { "shipdate": { "$lte": 19980801 } }, 
    { "$group": { 
     "_id": { 
      "returnflag": "$returnflag", 
      "linestatus": "$linestatus" 
     }, 
     "count": { "$sum": 1 }, 
     "sum_qty": { "$sum": "$quantity" }, 
     "avg_qty": { "$avg": "$quantity" }, 
     "sum_base_price": { "$sum": "$extendedprice" }, 
     "avg_base_price": { "$avg": "$extendedprice" }, 
     "sum_disc_price": { 
      "$sum": { 
       "$multiply": [ 
        "$extendedprice", 
        { "$subtract": [ 1, "$discount" ] } 
       ] 
      } 
     }, 
     "avg_disc_price": { 
      "$avg": { 
       "$multiply": [ 
        "$extendedprice", 
        { "$subtract": [ 1, "$discount" ] } 
       ] 
      } 
     }, 
     "sum_charge": { 
      "$sum": { 
       "$multiply": [ 
        "$extendedprice", 
        { "$subtract": [ 1, "$discount" ] }, 
        { "$add": [ 1, "$tax" ] } 
       ] 
      } 
     }, 
     "avg_disc": { "$avg": "$discount" } 
    }} 
]) 

ネイティブコード化された操作で全て同じことを行い、非常に効率的$groupパイプラインステージ演算子として集約フレームワーク。他の数学演算と同様に、$sum$avgアキュムレータが組み込まれています。

要するに、「ネイティブコード化された」「JavaScript解釈」に依存しないため、実行は、.group()が提供できるものよりもはるかに高速です。加えて、理解するのはかなり簡単です。 Javaへ

List<Document> pipeline = Arrays.<Document>asList(
    new Document(
    "$match", new Document(
     "shipdate", new Document(
     "$lte", 19980801    
    ) 
    ) 
), 
    new Document(
    "$group", new Document(
     "_id", new Document(
     "returnflag", "$returnflag" 
    ).append("linestatus", "$linestatus") 
    ).append(
     "count", new Document("$sum", 1) 
    ).append(
     "sum_qty", new Document("$sum", "$quantity") 
    ).append(
     "avg_qty", new Document("$avg", "$quantity") 
    ).append(
     "sum_base_price", new Document("$sum", "$extendedprice") 
    ).append(
     "avg_base_price", new Document("$avg", "$extendedprice") 
    ).append(
     "sum_disc_price", new Document(
     "$sum", new Document(
      "$multiply", Arrays.asList(
      "$extendedprice", 
      new Document(
       "$subtract", Arrays.asList(1, "$discount") 
      ) 
     ) 
     ) 
    ) 
    ).append(
     "avg_disc_price", new Document(
     "$avg", new Document(
      "$multiply", Arrays.asList(
      "$extendedprice", 
      new Document(
       "$subtract", Arrays.asList(1, "$discount") 
      ) 
     ) 
     ) 
    ) 
    ).append(
     "sum_charge", new Document(
     "$sum", new Document(
      "$multiply", Arrays.asList(
      "$extendedprice", 
      new Document(
       "$subtract", Arrays.asList(1, "$discount") 
      ), 
      new Document(
       "$add", Arrays.asList(1, "$tax") 
      ) 
     ) 
     ) 
    ) 
    ).append(
     "avg_disc", new Document("$avg", "$discount") 
    ) 
) 
); 

AggregateIterable<Document> result = collection.aggregate(pipeline); 
+0

ようなものになるだろうという翻訳

私は知っているが、私は集約フレームワークを使用してソリューションを持っていると私はマップと同じ結果を必要とするが、比較するために減らす...私が呼び出すためのJavaを使用する必要があります両方の場合。 – duknust

+1

@duknustなぜmapReduceが必要だと思いますか?ここでの説明は、 '.aggregate()'を使うほうが簡単であるだけでなく、実際には** far **よりも優れていることを示しています。 mapReduceが '.aggregate()'で性能や規模を競うことはできません。また、Javaコードも入手できます。あなたのコメントはあなたが答えを完全に読んでいないことを示唆しています。私はあなたがして、レッスンを学ぶことをお勧めします。 –

+1

@duknustもちろん、もう一つのことは、コード化された関数とシェルで試したものが['.group()'](https://docs.mongodb.org/manual/reference/method)であることです。 /db.collection.group/)メソッドを使用します。したがって、JavaScriptコードでさえ、あなたがすでにコード化したものから 'mapReduce'に合うようにかなりの変更が必要になります。ですから、Javaで '.group()'を呼び出すか、 'mapReduce'のすべてのコードを変更します。しかし、一般的な要約は、あなたがこれを行うべきではないということです。図示のように '.aggregate()'を使用してください。はるかに良いです。これはあなたがここで学ぶことを意味しているものです。 –

関連する問題