質問

次のデータを集計したいと考えています

{
   "user": "user1",
   "error": true 
}
{
   "user": "user2",
   "error": false
}
{
   "user": "user1",
   "error": false
}

の中へ

{
     "_id": "user1",
     "errorCount": 1,
     "totalCount": 2
},
{
     "_id": "user2",
     "errorCount": 0,
     "totalCount": 1
}

$cond 演算子を使用すると、次のようにしてこれを実現できます。

$group: {
    _id: "$user",
    errorCount : { "$sum" : {"$cond" : ["$error", 1, 0]}},
    totalCount : { "$sum" : 1 }
}

ただし、私は $cond をまだサポートしていない Spring-data-mongodb (1.3.4-RELEASE 時点) を使用しているため、これを行うことができませんでした。

$cond を使わずに同じ集計を行う方法はありますか?

役に立ちましたか?

解決

Spring データにまだ「関数インターフェイス」がない場合でも、これに拘束されることはありません。(ところで、JIRA を育ててください)

ネイティブ フォームを取得し、パイプラインで BasicDBObject タイプを使用するだけです。したがって、原則的には次のようになります。

    DBCollection myCollection = mongoOperation.getCollection("collection");

    <result cast> = myCollection.aggregate(<pipeline here>);

Spring データは抽象化を提供しますが、 ではない の使用を禁止する ネイティブ ドライバーの機能。それは実際に あなたにあげる 上で説明したように、アクセサはそれらを使用します。

他のヒント

Neil Lunn の提案のおかげで、$cond で spring-data からの集計サポートを使用できるようになりました。これを行うには、DBObject を取り込むための AggregationOperation インターフェイスを実装する必要があります。

public class DBObjectAggregationOperation implements AggregationOperation {
  private DBObject operation;

  public DBObjectAggregationOperation (DBObject operation) {
    this.operation = operation;
  }

  @Override
  public DBObject toDBObject(AggregationOperationContext context) {
    return context.getMappedObject(operation);
  }
}

これで、TypeAggregation で通常どおり使用できるようになります。

DBObject operation = (DBObject)JSON.parse ("your pipleline here...");
TypedAggregation<UserStats> aggregation = newAggregation(User.class,
    new DBObjectAggregationOperation(operation)
    );
AggregationResults<UserStats> result = mongoTemplate.aggregate(aggregation, UserStats.class); 

このアプローチにより、フレームワークでまだ定義されていない集計演算子を使用できるようになります。ただし、これは spring-data によって設定された検証もバイパスするため、注意して使用する必要があります。
フレームワークを通じて $cond 演算子を適切にサポートしたい場合は、投票してください。 https://jira.springsource.org/browse/DATAMONGO-861

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top