Merge remote-tracking branch 'origin/master'

This commit is contained in:
DiK
2019-10-10 23:41:56 +02:00
10 changed files with 87 additions and 12 deletions
+4 -4
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>ru.otus.example</groupId>
@@ -15,9 +15,9 @@
<description>Demo project for MongoDB</description>
<properties>
<java.version>1.8</java.version>
<maven.compiler.sourcre>1.8.</maven.compiler.sourcre>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>11</java.version>
<maven.compiler.sourcre>11</maven.compiler.sourcre>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
@@ -30,8 +30,7 @@ public class InitMongoDBDataChangeLog {
@ChangeSet(order = "002", id = "initStudents", author = "stvort", runAlways = true)
public void initStudents(MongoTemplate template){
val student = new Student("Student #1", springDataKnowledge, mongockKnowledge);
template.save(student);
template.save(new Student("Student #1", springDataKnowledge, mongockKnowledge));
}
@ChangeSet(order = "003", id = "Teacher", author = "stvort", runAlways = true)
@@ -1,6 +1,12 @@
package ru.otus.example.mongodbdemo.repositories;
import ru.otus.example.mongodbdemo.model.Knowledge;
import java.util.List;
public interface StudentRepositoryCustom {
List<Knowledge> getStudentExperienceById(String studentId);
long getExperienceArrayLengthByStudentId(String id);
void removeExperienceArrayElementsById(String id);
}
@@ -3,15 +3,22 @@ package ru.otus.example.mongodbdemo.repositories;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import ru.otus.example.mongodbdemo.model.Knowledge;
import ru.otus.example.mongodbdemo.model.Student;
import ru.otus.example.mongodbdemo.utils.RawResultPrinter;
import java.util.List;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.aggregation.ObjectOperators.ObjectToArray.valueOfToArray;
import static org.springframework.data.mongodb.core.query.Criteria.where;
@RequiredArgsConstructor
@@ -23,16 +30,36 @@ public class StudentRepositoryCustomImpl implements StudentRepositoryCustom {
}
private final MongoTemplate mongoTemplate;
private final RawResultPrinter rawResultPrinter;
public long getExperienceArrayLengthByStudentId(String id) {
@Override
public List<Knowledge> getStudentExperienceById(String studentId) {
Aggregation aggregation = newAggregation(
match(Criteria.where("id").is(studentId))
, unwind("experience")
, project().andExclude("_id").and(valueOfToArray("experience")).as("experience_map")
, project().and("experience_map").arrayElementAt(1).as("experience_id_map")
, project().and("experience_id_map.v").as("experience_id")
, lookup("knowledge", "experience_id", "_id", "experience")
, project().and("experience._id").as("_id").and("experience.name").as("name")
);
Document rawResults = mongoTemplate.aggregate(aggregation, Student.class, Knowledge.class).getRawResults();
rawResultPrinter.prettyPrintRawResult(rawResults);
return mongoTemplate.aggregate(aggregation, Student.class, Knowledge.class).getMappedResults();
}
@Override
public long getExperienceArrayLengthByStudentId(String studentId) {
val aggregation = Aggregation.newAggregation(
Aggregation.match(where("id").is(id)),
Aggregation.project().andExclude("_id").and("experience").size().as("size"));
match(where("id").is(studentId)),
project().andExclude("_id").and("experience").size().as("size"));
val arraySizeProjection = mongoTemplate.aggregate(aggregation, Student.class, ArraySizeProjection.class).getUniqueMappedResult();
return arraySizeProjection == null ? 0 : arraySizeProjection.getSize();
}
@Override
public void removeExperienceArrayElementsById(String id) {
val query = Query.query(Criteria.where("$id").is(new ObjectId(id)));
val update = new Update().pull("experience", query);
@@ -0,0 +1,8 @@
package ru.otus.example.mongodbdemo.utils;
import org.bson.Document;
public interface RawResultPrinter {
@SuppressWarnings("unchecked")
void prettyPrintRawResult(Document document);
}
@@ -0,0 +1,18 @@
package ru.otus.example.mongodbdemo.utils;
import org.bson.Document;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class RawResultPrinterImpl implements RawResultPrinter {
@SuppressWarnings("unchecked")
@Override
public void prettyPrintRawResult(Document document) {
List<Document> results = (List<Document>) document.get("results");
String resultsAsString = results.stream().map(Document::toString).collect(Collectors.joining("\n"));
System.out.println(resultsAsString);
}
}
@@ -4,3 +4,6 @@ spring:
uri: mongodb://localhost
port: 27017
database: awesomeMongo
logging:
level:
root: ERROR
@@ -3,11 +3,12 @@ package ru.otus.example.mongodbdemo.repositories;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.context.annotation.Import;
import ru.otus.example.mongodbdemo.utils.RawResultPrinterImpl;
@DataMongoTest
@EnableConfigurationProperties
@ComponentScan({"ru.otus.example.mongodbdemo.config", "ru.otus.example.mongodbdemo.repositories"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@Import(RawResultPrinterImpl.class)
public abstract class AbstractRepositoryTest {
}
@@ -10,6 +10,8 @@ import ru.otus.example.mongodbdemo.model.Student;
import ru.otus.example.mongodbdemo.repositories.AbstractRepositoryTest;
import ru.otus.example.mongodbdemo.repositories.StudentRepository;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("StudentRepository при наличии listener-ов в контексте ")
@@ -28,4 +30,12 @@ class StudentRepositoryWithListenersTest extends AbstractRepositoryTest {
assertThat(actual.getName()).isEqualTo(student.getName());
}
@DisplayName("должен возвращать корректный список знаний студента")
@Test
void shouldReturnCorrectStudentKnowledgeList(){
val student = studentRepository.findAll().get(0);
List<Knowledge> knowledgeList = studentRepository.getStudentExperienceById(student.getId());
assertThat(knowledgeList).containsExactlyInAnyOrderElementsOf(student.getExperience());
}
}
@@ -5,4 +5,7 @@ spring:
database: test
#uri: mongodb://localhost
#port: 27017
#database: awesomeMongo
#database: awesomeMongo
logging:
level:
root: ERROR