Switch MongoDB samples to records.

See #606.
This commit is contained in:
Mark Paluch
2021-04-28 15:18:59 +02:00
parent b44dc3dea1
commit e565f33872
69 changed files with 395 additions and 555 deletions

View File

@@ -17,20 +17,12 @@ package example.springdata.mongodb.aggregation;
import java.util.List;
import lombok.Value;
/**
* A DTO to represent invoices.
*
* @author Thomas Darimont
* @author Oliver Gierke
*/
@Value
public class Invoice {
public record Invoice(String orderId, double taxAmount, double netAmount, double totalAmount, List<LineItem> items) {
private final String orderId;
private final double taxAmount;
private final double netAmount;
private final double totalAmount;
private final List<LineItem> items;
}

View File

@@ -15,9 +15,6 @@
*/
package example.springdata.mongodb.aggregation;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.data.annotation.PersistenceConstructor;
/**
@@ -26,18 +23,15 @@ import org.springframework.data.annotation.PersistenceConstructor;
* @author Thomas Darimont
* @author Oliver Gierke
*/
@Data
@RequiredArgsConstructor(onConstructor = @__(@PersistenceConstructor))
public class LineItem {
private final String caption;
private final double price;
public record LineItem(String caption, double price, int quantity) {
int quantity = 1;
public LineItem(String caption, double price, int quantity) {
this(caption, price);
this.quantity = quantity;
@PersistenceConstructor
public LineItem {
}
public LineItem(String caption, double price) {
this(caption, price, 1);
}
}

View File

@@ -48,7 +48,7 @@ class OrderRepositoryImpl implements OrderRepositoryCustom {
@Override
public Invoice getInvoiceFor(Order order) {
AggregationResults<Invoice> results = operations.aggregate(newAggregation(Order.class, //
var results = operations.aggregate(newAggregation(Order.class, //
match(where("id").is(order.getId())), //
unwind("items"), //
project("id", "customerId", "items") //

View File

@@ -15,17 +15,11 @@
*/
package example.springdata.mongodb.aggregation;
import lombok.Value;
import org.springframework.data.annotation.Id;
/**
* @author Christoph Strobl
*/
@Value
public class OrdersPerCustomer {
public record OrdersPerCustomer(@Id String customerId, Long total) {
@Id //
private String customerId;
private Long total;
}

View File

@@ -54,33 +54,33 @@ public class OrderRepositoryIntegrationTests {
@Test
public void createsInvoiceViaProgrammaticAggregation() {
Order order = new Order("c42", new Date()).//
var order = new Order("c42", new Date()).//
addItem(product1).addItem(product2).addItem(product3);
order = repository.save(order);
Invoice invoice = repository.getInvoiceFor(order);
var invoice = repository.getInvoiceFor(order);
assertThat(invoice).isNotNull();
assertThat(invoice.getOrderId()).isEqualTo(order.getId());
assertThat(invoice.getNetAmount()).isCloseTo(8.3D, offset(0.00001));
assertThat(invoice.getTaxAmount()).isCloseTo(1.577D, offset(0.00001));
assertThat(invoice.getTotalAmount()).isCloseTo(9.877, offset(0.00001));
assertThat(invoice.orderId()).isEqualTo(order.getId());
assertThat(invoice.netAmount()).isCloseTo(8.3D, offset(0.00001));
assertThat(invoice.taxAmount()).isCloseTo(1.577D, offset(0.00001));
assertThat(invoice.totalAmount()).isCloseTo(9.877, offset(0.00001));
}
@Test
public void createsInvoiceViaDeclarativeAggregation() {
Order order = new Order("c42", new Date()).//
var order = new Order("c42", new Date()).//
addItem(product1).addItem(product2).addItem(product3);
order = repository.save(order);
Invoice invoice = repository.aggregateInvoiceForOrder(order.getId());
var invoice = repository.aggregateInvoiceForOrder(order.getId());
assertThat(invoice).isNotNull();
assertThat(invoice.getOrderId()).isEqualTo(order.getId());
assertThat(invoice.getNetAmount()).isCloseTo(8.3D, offset(0.00001));
assertThat(invoice.getTaxAmount()).isCloseTo(1.577D, offset(0.00001));
assertThat(invoice.getTotalAmount()).isCloseTo(9.877, offset(0.00001));
assertThat(invoice.orderId()).isEqualTo(order.getId());
assertThat(invoice.netAmount()).isCloseTo(8.3D, offset(0.00001));
assertThat(invoice.taxAmount()).isCloseTo(1.577D, offset(0.00001));
assertThat(invoice.totalAmount()).isCloseTo(9.877, offset(0.00001));
}
@Test

View File

@@ -18,10 +18,6 @@ package example.springdata.mongodb.aggregation;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import lombok.Getter;
import lombok.Value;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.List;
@@ -37,8 +33,6 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.ArithmeticOperators;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators;
import org.springframework.data.mongodb.core.aggregation.BucketAutoOperation.Granularities;
@@ -67,10 +61,10 @@ public class SpringBooksIntegrationTests {
if (operations.count(new Query(), "books") == 0) {
File file = new ClassPathResource("books.json").getFile();
String content = Files.contentOf(file, StandardCharsets.UTF_8);
Document wrapper = Document.parse("{wrapper: " + content + "}");
List<Object> books = wrapper.getList("wrapper", Object.class);
var file = new ClassPathResource("books.json").getFile();
var content = Files.contentOf(file, StandardCharsets.UTF_8);
var wrapper = Document.parse("{wrapper: " + content + "}");
var books = wrapper.getList("wrapper", Object.class);
operations.insert(books, "books");
}
@@ -82,11 +76,14 @@ public class SpringBooksIntegrationTests {
@Test
public void shouldRetrieveOrderedBookTitles() {
Aggregation aggregation = newAggregation( //
record BookTitle(String title) {
}
var aggregation = newAggregation( //
sort(Direction.ASC, "volumeInfo.title"), //
project().and("volumeInfo.title").as("title"));
AggregationResults<BookTitle> result = operations.aggregate(aggregation, "books", BookTitle.class);
var result = operations.aggregate(aggregation, "books", BookTitle.class);
assertThat(result.getMappedResults())//
.extracting("title")//
@@ -99,13 +96,13 @@ public class SpringBooksIntegrationTests {
@Test
public void shouldRetrieveBooksPerPublisher() {
Aggregation aggregation = newAggregation( //
var aggregation = newAggregation( //
group("volumeInfo.publisher") //
.count().as("count"), //
sort(Direction.DESC, "count"), //
project("count").and("_id").as("publisher"));
AggregationResults<BooksPerPublisher> result = operations.aggregate(aggregation, "books", BooksPerPublisher.class);
var result = operations.aggregate(aggregation, "books", BooksPerPublisher.class);
assertThat(result).hasSize(27);
assertThat(result).extracting("publisher").containsSequence("Apress", "Packt Publishing Ltd");
@@ -118,20 +115,20 @@ public class SpringBooksIntegrationTests {
@Test
public void shouldRetrieveBooksPerPublisherWithTitles() {
Aggregation aggregation = newAggregation( //
var aggregation = newAggregation( //
group("volumeInfo.publisher") //
.count().as("count") //
.addToSet("volumeInfo.title").as("titles"), //
sort(Direction.DESC, "count"), //
project("count", "titles").and("_id").as("publisher"));
AggregationResults<BooksPerPublisher> result = operations.aggregate(aggregation, "books", BooksPerPublisher.class);
var result = operations.aggregate(aggregation, "books", BooksPerPublisher.class);
BooksPerPublisher booksPerPublisher = result.getMappedResults().get(0);
var booksPerPublisher = result.getMappedResults().get(0);
assertThat(booksPerPublisher.getPublisher()).isEqualTo("Apress");
assertThat(booksPerPublisher.getCount()).isEqualTo(26);
assertThat(booksPerPublisher.getTitles()).contains("Expert Spring MVC and Web Flow", "Pro Spring Boot");
assertThat(booksPerPublisher.publisher()).isEqualTo("Apress");
assertThat(booksPerPublisher.count()).isEqualTo(26);
assertThat(booksPerPublisher.titles()).contains("Expert Spring MVC and Web Flow", "Pro Spring Boot");
}
/**
@@ -140,18 +137,18 @@ public class SpringBooksIntegrationTests {
@Test
public void shouldRetrieveDataRelatedBooks() {
Aggregation aggregation = newAggregation( //
var aggregation = newAggregation( //
match(Criteria.where("volumeInfo.title").regex("data", "i")), //
replaceRoot("volumeInfo"), //
project("title", "authors"), //
sort(Direction.ASC, "title"));
AggregationResults<BookAndAuthors> result = operations.aggregate(aggregation, "books", BookAndAuthors.class);
var result = operations.aggregate(aggregation, "books", BookAndAuthors.class);
BookAndAuthors bookAndAuthors = result.getMappedResults().get(1);
var bookAndAuthors = result.getMappedResults().get(1);
assertThat(bookAndAuthors.getTitle()).isEqualTo("Spring Data");
assertThat(bookAndAuthors.getAuthors()).contains("Mark Pollack", "Oliver Gierke", "Thomas Risberg", "Jon Brisbin",
assertThat(bookAndAuthors.title()).isEqualTo("Spring Data");
assertThat(bookAndAuthors.authors()).contains("Mark Pollack", "Oliver Gierke", "Thomas Risberg", "Jon Brisbin",
"Michael Hunger");
}
@@ -161,7 +158,10 @@ public class SpringBooksIntegrationTests {
@Test
public void shouldRetrievePagesPerAuthor() {
Aggregation aggregation = newAggregation( //
record PagesPerAuthor(@Id String author, int totalPageCount, int approxWritten) {
}
var aggregation = newAggregation( //
match(Criteria.where("volumeInfo.authors").exists(true)), //
replaceRoot("volumeInfo"), //
project("authors", "pageCount") //
@@ -174,13 +174,13 @@ public class SpringBooksIntegrationTests {
.sum("pagesPerAuthor").as("approxWritten"), //
sort(Direction.DESC, "totalPageCount"));
AggregationResults<PagesPerAuthor> result = operations.aggregate(aggregation, "books", PagesPerAuthor.class);
var result = operations.aggregate(aggregation, "books", PagesPerAuthor.class);
PagesPerAuthor pagesPerAuthor = result.getMappedResults().get(0);
var pagesPerAuthor = result.getMappedResults().get(0);
assertThat(pagesPerAuthor.getAuthor()).isEqualTo("Josh Long");
assertThat(pagesPerAuthor.getTotalPageCount()).isEqualTo(1892);
assertThat(pagesPerAuthor.getApproxWritten()).isEqualTo(573);
assertThat(pagesPerAuthor.author()).isEqualTo("Josh Long");
assertThat(pagesPerAuthor.totalPageCount()).isEqualTo(1892);
assertThat(pagesPerAuthor.approxWritten()).isEqualTo(573);
}
/**
@@ -189,7 +189,7 @@ public class SpringBooksIntegrationTests {
@Test
public void shouldCategorizeBooksInBuckets() {
Aggregation aggregation = newAggregation( //
var aggregation = newAggregation( //
replaceRoot("volumeInfo"), //
match(Criteria.where("pageCount").exists(true)),
bucketAuto("pageCount", 10) //
@@ -197,20 +197,20 @@ public class SpringBooksIntegrationTests {
.andOutput("title").push().as("titles") //
.andOutput("titles").count().as("count"));
AggregationResults<BookFacetPerPage> result = operations.aggregate(aggregation, "books", BookFacetPerPage.class);
var result = operations.aggregate(aggregation, "books", BookFacetPerPage.class);
List<BookFacetPerPage> mappedResults = result.getMappedResults();
var mappedResults = result.getMappedResults();
BookFacetPerPage facet_20_to_100_pages = mappedResults.get(0);
assertThat(facet_20_to_100_pages.getId().getMin()).isEqualTo(20);
assertThat(facet_20_to_100_pages.getId().getMax()).isEqualTo(100);
assertThat(facet_20_to_100_pages.getCount()).isEqualTo(12);
var facet_20_to_100_pages = mappedResults.get(0);
assertThat(facet_20_to_100_pages.id().min()).isEqualTo(20);
assertThat(facet_20_to_100_pages.id().max()).isEqualTo(100);
assertThat(facet_20_to_100_pages.count()).isEqualTo(12);
BookFacetPerPage facet_100_to_500_pages = mappedResults.get(1);
assertThat(facet_100_to_500_pages.getId().getMin()).isEqualTo(100);
assertThat(facet_100_to_500_pages.getId().getMax()).isEqualTo(500);
assertThat(facet_100_to_500_pages.getCount()).isEqualTo(63);
assertThat(facet_100_to_500_pages.getTitles()).contains("Spring Data");
var facet_100_to_500_pages = mappedResults.get(1);
assertThat(facet_100_to_500_pages.id().min()).isEqualTo(100);
assertThat(facet_100_to_500_pages.id().max()).isEqualTo(500);
assertThat(facet_100_to_500_pages.count()).isEqualTo(63);
assertThat(facet_100_to_500_pages.titles()).contains("Spring Data");
}
/**
@@ -221,7 +221,7 @@ public class SpringBooksIntegrationTests {
@SuppressWarnings("unchecked")
public void shouldCategorizeInMultipleFacetsByPriceAndAuthor() {
Aggregation aggregation = newAggregation( //
var aggregation = newAggregation( //
match(Criteria.where("volumeInfo.authors").exists(true).and("volumeInfo.publisher").exists(true)),
facet() //
.and(match(Criteria.where("saleInfo.listPrice").exists(true)), //
@@ -240,55 +240,23 @@ public class SpringBooksIntegrationTests {
.andOutput("author").push().as("authors") //
).as("authors"));
AggregationResults<Document> result = operations.aggregate(aggregation, "books", Document.class);
var result = operations.aggregate(aggregation, "books", Document.class);
Document uniqueMappedResult = result.getUniqueMappedResult();
var uniqueMappedResult = result.getUniqueMappedResult();
assertThat((List<Object>) uniqueMappedResult.get("prices")).hasSize(3);
assertThat((List<Object>) uniqueMappedResult.get("authors")).hasSize(8);
}
@Value
@Getter
static class BookTitle {
String title;
record BooksPerPublisher(String publisher, int count, List<String> titles) {
}
@Value
@Getter
static class BooksPerPublisher {
String publisher;
int count;
List<String> titles;
record BookAndAuthors(String title, List<String> authors) {
}
@Value
@Getter
static class BookAndAuthors {
String title;
List<String> authors;
record BookFacetPerPage(BookFacetPerPageId id, int count, List<String> titles) {
}
@Value
@Getter
static class PagesPerAuthor {
@Id String author;
int totalPageCount;
int approxWritten;
}
@Value
@Getter
static class BookFacetPerPage {
BookFacetPerPageId id;
int count;
List<String> titles;
}
@Value
@Getter
static class BookFacetPerPageId {
int min;
int max;
record BookFacetPerPageId(int min, int max) {
}
}