Domanda

Sto cercando di aggregare i seguenti dati

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

In

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

Con l'operatore con cond, questo può essere ottenuto utilizzando:

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

Tuttavia, dal momento che sto usando Spring-data-mongodb che non supporta ancora $cond (a partire da 1.3.4-RELEASE), non ho potuto farlo.

C'è un modo per fare la stessa aggregazione senza con cond?

È stato utile?

Soluzione

Non sei vincolato a questo anche se non esiste ancora alcuna "interfaccia funzionale" nei dati Spring.(BTW, sollevare un JIRA)

Basta ottenere il modulo nativo e utilizzare i tipi BasicDBObject nella pipeline.Quindi in linea di principio:

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

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

I dati di primavera ti danno astrazioni, ma non lo fa vietare l'uso del nativo funzioni del driver.In realtà dare accessori per usarli, come ho dimostrato sopra.

Altri suggerimenti

Grazie al suggerimento di Neil Lunn, sono riuscito a ottenere con cond utilizzando il supporto di aggregazione da spring-data.Per fare ciò, è necessario implementare l'interfaccia AggregationOperation per prendere in un DBObject.

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);
  }
}

Quindi sarai in grado di usarlo normalmente in 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); 

Questo approccio ti consentirà di utilizzare qualsiasi operatore di aggregazione non ancora definito nel framework.Tuttavia, ha anche bypassato la convalida messa in atto da spring-data e dovrebbe essere usata con cautela.
Si prega di votare se si desidera che l'operatore $cond sia supportato correttamente attraverso il framework: https://jira.springsource.org/browse/DATAMONGO-861

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top