Spring Data MongoDB应用程序设计和数据聚合 [英] Spring data mongodb application design and data aggregation

查看:137
本文介绍了Spring Data MongoDB应用程序设计和数据聚合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 spring data mongo angularjs . 这是模型:

I was developing a little application with spring data mongo and angularjs. Here is model :

public class Lease {
        @Id
        private String id;
        private long created;
        private Lessor lessor;
        private Lessee lessee;
      }

public class Payment {
        @Id
        private String id;
        private Integer month;
        private Integer year;
        private Long amount;
        private String leaseId;
     }

我没有嵌入付款模型,因为我需要它具有一个ID并以其自己的形式对其进行编辑. 在应用程序的主页上,它表示按月付款的租赁清单.在列表上方的选择中选择年份.

I did not embed Payment model as I need it to have an id and edit it in its own form. On the main page of the app it represents a list of leases with payments by month. The year is chosen in a select above the list.

如何更好地按月使用其余付款来更好地分配租赁:可能是先进行租赁,然后将ID注入付款,还是有更好的解决方案?目前,我选择使用聚合:

How to better load leases with payments by year by month using rest: may be first load leases then inject ids to payments or there is a better solution? For the moment I chose to use aggregation:

LookupOperation lookupOperation = LookupOperation.newLookup().
                                  from("payment").
                                  localField("leaseId").
                                  foreignField("id").
                                  as("payments");

AggregationOperation match = Aggregation.match(Criteria.where("payments.year").is(year));
Aggregation aggregation = Aggregation.newAggregation(lookupOperation, match);

return mongoOperations.aggregate(aggregation, "lease", LeaseAggregation.class).getMappedResults();

问题是匹配在这里是排他性的,例如,如果2017年没有付款,则租赁清单为空.我在mongo中看到"addFields"功能,该功能尚未在Spring数据mongodb中实现.对我来说,更好的json返回值是:

The problem is that match is exclusive here and for example if there are no payments in 2017, list of leases is empty. I saw "addFields" functionality in mongo by it is not yet implemented in spring data mongodb. A better json return for me would be :

{"leases" : [{"id" : 123, "created" : 12324343434, "payments" : [123, 455, 343, 323, 344, null, null, 332, 323, 232, 333, 434}]}

其中付款将代表特定年份的十二个月.

where payments will represent twelve months of a particular year.

如何通过spring数据mongodb获得此信息?

How can I obtain this with spring data mongodb?

任何帮助将不胜感激!

推荐答案

每当Spring Data Mongo缺少您需要的AggregationOperation(重现$addFields$redact ...)时,就有一种解决方法(有些人可能说它又脏又快)解决方案)是直接使用com.mongodb.client工具将原始聚合传递给Spring:

Whenever Spring Data Mongo lacks an AggregationOperation you need (to reproduce $addFields, $redact...), a workaround (some may say quick and dirty solution) is to pass the raw aggregation to Spring, using directly the com.mongodb.client tools :

String collectionName = mongoTemplate.getCollectionName(Payment.class);
MongoCollection<Document> collection = mongoClient.getDatabase(mongoTemplate.getDb().getName()).getCollection(collectionName);

AggregateIterable<Document> ai = collection.aggregate(Arrays.asList(
    Document.parse(/* { "group" : { ... } } */)))

MongoCollection.aggregate()作为List<Document>传递到聚合管道(实际上,如上面建议的那样,使用Document.parse()以List<? extends Bson>的原始形式传递),您当然也可以使用new Document()使其外观更像是适当的OOP代码.当原始聚合很复杂,或者由于嵌套文档的许多嵌套组件对我来说太冗长时,我倾向于使用原始形式.

MongoCollection.aggregate() is passed the aggregation pipeline as List<Document> (in fact List<? extends Bson> in raw form as suggested above using Document.parse(), and you can of course also use new Document() to make it look more like proper OOP code. I tend to use the raw form when the raw aggregation is complex or as many nested components for nested Document are too much verbose for me, but that's a matter of taste.

这篇关于Spring Data MongoDB应用程序设计和数据聚合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆