diff --git a/elasticsearch/example/src/main/java/example/springdata/elasticsearch/speaker/Speaker.java b/elasticsearch/example/src/main/java/example/springdata/elasticsearch/speaker/Speaker.java new file mode 100644 index 000000000..c0d55d887 --- /dev/null +++ b/elasticsearch/example/src/main/java/example/springdata/elasticsearch/speaker/Speaker.java @@ -0,0 +1,23 @@ +package example.springdata.elasticsearch.speaker; + +import lombok.Builder; +import lombok.Data; + +/** + * Speaker of a talk. + */ +@Data +@Builder +public class Speaker { + + /** + * Speaker name. + */ + private String name; + + /** + * Speaker position. + */ + private String position; +} + diff --git a/elasticsearch/example/src/main/java/example/springdata/elasticsearch/speaker/package-info.java b/elasticsearch/example/src/main/java/example/springdata/elasticsearch/speaker/package-info.java new file mode 100644 index 000000000..def2b0f75 --- /dev/null +++ b/elasticsearch/example/src/main/java/example/springdata/elasticsearch/speaker/package-info.java @@ -0,0 +1,4 @@ +/** + * Domain classes for speaker examples in Spring Data Elasticsearch. + */ +package example.springdata.elasticsearch.speaker; diff --git a/elasticsearch/example/src/main/java/example/springdata/elasticsearch/talk/Talk.java b/elasticsearch/example/src/main/java/example/springdata/elasticsearch/talk/Talk.java new file mode 100644 index 000000000..67b108142 --- /dev/null +++ b/elasticsearch/example/src/main/java/example/springdata/elasticsearch/talk/Talk.java @@ -0,0 +1,38 @@ +package example.springdata.elasticsearch.talk; + +import example.springdata.elasticsearch.speaker.Speaker; + +import java.util.List; + +import lombok.Builder; +import lombok.Data; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; + +/** + * Elasticsearch talk document. + */ +@Data +@Builder +@Document(indexName = "talks") +public class Talk { + + /** + * Document id. + */ + @Id + private String id; + + /** + * Talk title. + */ + private String title; + + /** + * Speakers of this talk. + */ + @Field(type = FieldType.Nested) + private List speakers; +} diff --git a/elasticsearch/example/src/main/java/example/springdata/elasticsearch/talk/package-info.java b/elasticsearch/example/src/main/java/example/springdata/elasticsearch/talk/package-info.java new file mode 100644 index 000000000..4a30c75ec --- /dev/null +++ b/elasticsearch/example/src/main/java/example/springdata/elasticsearch/talk/package-info.java @@ -0,0 +1,4 @@ +/** + * Domain classes for talk examples in Spring Data Elasticsearch. + */ +package example.springdata.elasticsearch.talk; diff --git a/elasticsearch/example/src/test/java/example/springdata/elasticsearch/conference/ElasticsearchOperationsTest.java b/elasticsearch/example/src/test/java/example/springdata/elasticsearch/conference/ElasticsearchOperationsTest.java index 4a52ba8a8..f0e1c6696 100644 --- a/elasticsearch/example/src/test/java/example/springdata/elasticsearch/conference/ElasticsearchOperationsTest.java +++ b/elasticsearch/example/src/test/java/example/springdata/elasticsearch/conference/ElasticsearchOperationsTest.java @@ -17,8 +17,12 @@ import static org.assertj.core.api.Assertions.*; +import example.springdata.elasticsearch.speaker.Speaker; +import example.springdata.elasticsearch.talk.Talk; + import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -103,4 +107,38 @@ void geoSpatialSearch() { assertThat(result).hasSize(2); } + + @Test + void criteriaQueryOnNestedSpeakers() { + + String speakerName = "Ali"; + var speaker = Speaker.builder() + .name(speakerName) + .position("Developer") + .build(); + + var talkWithSpeaker = Talk.builder() + .id("1") + .title("Spring & Elasticsearch") + .speakers(List.of(speaker)) + .build(); + + var talkWithoutSpeaker = Talk.builder() + .id("2") + .title("No Speakers Here") + .build(); + + operations.save(talkWithSpeaker); + operations.save(talkWithoutSpeaker); + + var criteria = new Criteria("speakers.name").is(speakerName); + var query = new CriteriaQuery(criteria); + + var result = operations.search(query, Talk.class); + + assertThat(result).hasSize(1); + assertThat(result.getSearchHits().get(0).getContent() + .getSpeakers().get(0).getName()) + .isEqualTo(speakerName); + } }