简体   繁体   English

Spring数据mongodb应用设计与数据聚合

[英]Spring data mongodb application design and data aggregation

I was developing a little application with spring data mongo and angularjs .我正在使用spring 数据 mongoangularjs开发一个小应用程序。 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;
     }

I did not embed Payment model as I need it to have an id and edit it in its own form.我没有嵌入支付模型,因为我需要它有一个 id 并以自己的形式编辑它。 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.在列表上方的选择中选择年份。

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?如何使用休息逐月更好地加载租赁:可能首先加载租赁,然后将 id 注入付款,或者有更好的解决方案? 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();

The problem is that match is exclusive here and for example if there are no payments in 2017, list of leases is empty.问题是匹配在这里是排他的,例如,如果 2017 年没有付款,则租赁列表为空。 I saw "addFields" functionality in mongo by it is not yet implemented in spring data mongodb.我在 mongo 中看到了“addFields”功能,因为它尚未在 spring 数据 mongodb 中实现。 A better json return for me would be :对我来说更好的 json 回报是:

{"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.其中付款将代表特定年份的十二个月。

How can I obtain this with spring data mongodb?我怎样才能用 spring 数据 mongodb 获得这个?

Any help would be appreciated!任何帮助,将不胜感激!

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 :每当春天数据蒙戈缺少AggregationOperation你需要(复制$addFields$redact ......),解决方法(有些人可能会说,快速和肮脏的解决方案)是将原始聚集到春天,直接使用该com.mongodb.client工具:

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() 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. MongoCollection.aggregate() 作为List<Document>传递给聚合管道(实际上List<? extends Bson>以上面建议的原始形式使用 Document.parse(),当然你也可以使用new Document()来制作它看起来更像是正确的 OOP 代码。当原始聚合很复杂或者嵌套文档的许多嵌套组件对我来说太冗长时,我倾向于使用原始表单,但这是一个品味问题。


2020 UPDATE. 2020 年更新。

Use this workaround instead.请改用此解决方法 With this it's easy to use both AggregationOperation provided by Spring and your own "raw" aggregation stages in the same place.有了这个,就可以很容易地在同一个地方使用 Spring 提供的 AggregationOperation 和你自己的“原始”聚合阶段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM