Quello che ti serve è il $redact
operatore nel framework di aggregazione che consente di elaborare la condizione logica di cui sopra con il $cond
operatore e utilizza le operazioni speciali $$KEEP
per "conservare" il documento in cui la condizione logica è vera o $$PRUNE
per "rimuovere" il documento in cui la condizione era falsa.
Questa operazione è simile all'avere un $project
pipeline che seleziona i campi nella raccolta e crea un nuovo campo che contiene il risultato della query della condizione logica e quindi un successivo $match
, tranne che $redact
utilizza una singola fase della pipeline che è più efficiente.
Considera il seguente esempio che dimostra il concetto precedente:
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$gte": [
{ "$divide": ["$Number1", "$Number2"] },
CONSTANT_VAR
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
Poiché non c'è nessun supporto per $redact
ancora operatore
(al momento della scrittura), una soluzione alternativa sarà implementare un AggregationOperation
interfaccia che racchiude l'operazione di aggregazione con una classe da inserire in un DBObject
:
public class RedactAggregationOperation implements AggregationOperation {
private DBObject operation;
public RedactAggregationOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
che puoi quindi utilizzare in TypeAggregation
:
Aggregation agg = newAggregation(
new RedactAggregationOperation(
new BasicDBObject(
"$redact",
new BasicDBObject(
"$cond", new BasicDBObject()
.append("if", new BasicDBObject(
"$gte", Arrays.asList(
new BasicDBObject(
"$divide", Arrays.asList( "$Number1", "$Number2" )
),
CONSTANT_VAR
)
)
)
.append("then", "$$KEEP")
.append("else", "$$PRUNE")
)
)
)
);
AggregationResults<Example> results = mongoTemplate.aggregate(
(TypedAggregation<Example>) agg, Example.class);
--AGGIORNAMENTO--
Follow-up dai commenti, per verificare la presenza di valori nulli o zero su Number2
campo nella divisione, dovresti annidare un $cond
espressione con la logica invece.
L'esempio seguente presuppone che tu abbia un valore segnaposto pari a 1 se Number2
non esiste/è nullo o ha un valore pari a zero:
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$gte": [
{
"$divide": [
"$Number1", {
"$cond": [
{
"$or": [
{ "$eq": ["$Number2", 0] },
{
"$eq": [
{ "$ifNull": ["$Number2", 0] }, 0
]
}
]
},
1, // placeholder value if Number2 is 0
"$Number2"
]
}
]
},
CONSTANT_VAR
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
Aggregazione di dati di primavera equivalente (non testata)
Aggregation agg = newAggregation(
new RedactAggregationOperation(
new BasicDBObject(
"$redact",
new BasicDBObject(
"$cond", Arrays.asList(
new BasicDBObject(
"$gte", Arrays.asList(
new BasicDBObject(
"$divide", Arrays.asList(
"$Number1",
new BasicDBObject(
"$cond", Arrays.asList(
new BasicDBObject( "$or": Arrays.asList(
new BasicDBObject("$eq", Arrays.asList("$Number2", 0)),
new BasicDBObject("$eq", Arrays.asList(
new BasicDBObject("$ifNull", Arrays.asList("$Number2", 0)), 0
)
)
)
),
1, // placeholder value if Number2 is 0
"$Number2"
)
)
)
),
CONSTANT_VAR
)
), "$$KEEP", "$$PRUNE"
)
)
)
)
);