在MongoDB Spring Data中使用多个方面 [英] Using multiple facets in MongoDB Spring Data
本文介绍了在MongoDB Spring Data中使用多个方面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想在一个聚合中运行多个方面以节省数据库往返.这是我的spring数据代码:
I want to run multiple facets in one aggregation to save db round trips. Here is my spring data code :
final BalancesDTO total
= this.mongoTemplate.aggregate(
newAggregation(
/*
* Get all fund transactions for this user
*/
match(where("userId").is(userId)),
/*
* Summarize Confirmed Debits
*/
facet( match(where("entryType").is(EntryType.DEBIT)
.andOperator(where("currentStatus").is(TransactionStatus.CONFIRMED))),
unwind("history"),
match(where("history.status").is(TransactionStatus.CONFIRMED)),
project().andExpression("history.amount").as("historyAmount"),
group().sum("historyAmount").as("total"),
project("total")
).as("totalConfirmedDebits"),
/*
* Summarize Confirmed Credits
*/
facet( match(where("entryType").is(EntryType.CREDIT)
.andOperator(where("currentStatus").is(TransactionStatus.CONFIRMED))),
unwind("history"),
match(where("history.status").is(TransactionStatus.CONFIRMED)),
project().andExpression("history.amount").as("historyAmount"),
group().sum("historyAmount").as("total"),
project("total")
).as("totalConfirmedCredits")
),
FundTransactions.class,
BalancesDTO.class)
.getUniqueMappedResult();
LOGGER.debug("total : {}",total.getTotalConfirmedDebits().get(0).getTotal());
当我运行上面的代码时,它给了我下面的异常:
When I run the above code it gives me below exception:
java.lang.IllegalArgumentException: Invalid reference 'history'!
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:100) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:72) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.UnwindOperation.toDocument(UnwindOperation.java:94) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDocument(AggregationOperationRenderer.java:55) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.FacetOperation$Facet.toDocuments(FacetOperation.java:224) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.FacetOperation$Facets.toDocument(FacetOperation.java:168) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.FacetOperation.toDocument(FacetOperation.java:87) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDocument(AggregationOperationRenderer.java:55) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.Aggregation.toDocument(Aggregation.java:585) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate$BatchAggregationLoader.prepareAggregationCommand(MongoTemplate.java:3124) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate$BatchAggregationLoader.aggregate(MongoTemplate.java:3107) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1937) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1832) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at io.tradehack.shared.fundtransactions.FundTransactionsRepositoryImpl.getFundBalances(FundTransactionsRepositoryImpl.java:41) ~[classes/:na]
at io.tradehack.shared.fundtransactions.FundTransactionsRepositoryImpl$$FastClassBySpringCGLIB$$89f7e1a0.invoke(<generated>) ~[classes/:na]
但是有趣的是,如果我删除了第二个方面,它就可以工作.发生此异常的原因可能是什么?
But the funny thing is if I removed the second facet section it works. What could be the reason for this exception?
以下是我要运行的等效mongodb命令:
Below is the equivalent mongodb command I want to run:
db.runCommand(
{ "aggregate" : "FundTransactions",
"pipeline" : [{ "$match" : { "userId" : "6cd984b9-1c17-402b-be9c-70614e0b8b8e"} },
{ "$facet" : { "totalConfirmedDebits" : [{ "$match" : { "entryType" : "DEBIT",
"$and" : [{ "currentStatus" : "CONFIRMED" }] } },
{ "$unwind" : "$history" },
{ "$match" : { "history.status" : "CONFIRMED" } },
{ "$project" : { "historyAmount" : "$history.amount" } },
{ "$group" : { "_id" : null,
"total" : { "$sum" : "$historyAmount" } } },
{ "$project" : { "total" : 1 } }],
"totalConfirmedCredits" : [{ "$match" : { "entryType" : "CREDIT",
"$and" : [{ "currentStatus" : "CONFIRMED" }] } },
{ "$unwind" : "$history" },
{ "$match" : { "history.status" : "CONFIRMED" } },
{ "$project" : { "historyAmount" : "$history.amount" } },
{ "$group" : { "_id" : null,
"total" : { "$sum" : "$historyAmount" } } },
{ "$project" : { "total" : 1 } }]
}
}],
"cursor" : { "batchSize" : 2147483647 } }
)
下面是示例数据:
{
"_id" : "dfe9dd63-6689-4e9f-8494-24efa6191db1",
"userId" : "6cd984b9-1c17-402b-be9c-70614e0b8b8e",
"entryType" : "DEBIT",
"type" : "DEPOSIT",
"createdDateTime" : ISODate("2018-11-11T03:00:00.000+00:00"),
"currentVersion" : 2,
"currentStatus" : "CONFIRMED",
"history" : [
{
"referenceId" : null,
"currency" : "USD",
"amount" : 1000000,
"comments" : "Initial fundings",
"updatedDateTime" : ISODate("2018-11-11T03:00:00.000+00:00"),
"status" : "PENDING",
"version" : 1
},
{
"referenceId" : null,
"currency" : "USD",
"amount" : 1001000,
"comments" : "Initial fundings",
"updatedDateTime" : ISODate("2018-11-11T04:00:00.000+00:00"),
"status" : "CONFIRMED",
"version" : 2
}
]
}
任何帮助将不胜感激.
推荐答案
您可以使用.and()
和.as()
方法链接多个方面的操作.您应将第二个facet
方法替换为and
方法,如下所示.
You can chain multiple facet operation using the .and()
and .as()
methods. You should replace the second facet
method with the and
method as below.
FacetOperation facets = facet(match(where("entryType").is(EntryType.DEBIT)
.andOperator(where("currentStatus").is(TransactionStatus.CONFIRMED))),
unwind("history"),
match(where("history.status").is(TransactionStatus.CONFIRMED)),
project().andExpression("history.amount").as("historyAmount"),
group().sum("historyAmount").as("total"),
project("total")
).as("totalConfirmedDebits"),
/*
* Summarize Confirmed Credits
*/
.and(match(where("entryType").is(EntryType.CREDIT)
.andOperator(where("currentStatus").is(TransactionStatus.CONFIRMED))),
unwind("history"),
match(where("history.status").is(TransactionStatus.CONFIRMED)),
project().andExpression("history.amount").as("historyAmount"),
group().sum("historyAmount").as("total"),
project("total")
).as("totalConfirmedCredits")
这篇关于在MongoDB Spring Data中使用多个方面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文