I\'m developing a system which is planning to use elasticsearch as an data repository. I\'m trying to choose the best way to develop my application that can index and query data
Also for like queries in Elasticsearch using Spring Boot you can make something like this:
Car car = new Car();
car.setName(new InnerField("name", "имя"));
QueryBuilder builder = QueryBuilders
.boolQuery()
.should(QueryBuilders.regexpQuery("name.ru", ".*" + name + ".*"))
.should(QueryBuilders.regexpQuery("name.kk", ".*" + name + ".*"))
.should(QueryBuilders.regexpQuery("name.qq", ".*" + name + ".*"));
NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(builder).build();
elasticsearchOperations.queryForList(build, tClass);
Spring data elasticsearch uses transport client, and transport client is not supported by AWS elasticsearch. AWS elasticsearch supports only HTTP clients. So i think the best java client for elasticsearch is JEST. It also provides support for AWS authentication using IAM.
Spring data elasticsearch supports most of the common feature set of elasticsearch including Nested, Inner Objects and Parent Child (recently).
When you said that want to use nested data (inner object), please be clear as elasticsearch has two concepts: Inner Object and Nested Object.
Detailed explanation can be found at managing relationship in elasticsearch
Person Entity:
@Document(indexName = "person" , type = "user")
public class Person {
@Id
private String id;
private String name;
@Field( type = FieldType.Nested)
private List<Car> car;
// setters-getters
}
Car Entity:
public class Car {
private String name;
private String model;
//setters and getters
}
Setting up data:
Person foo = new Person();
foo.setName("Foo");
foo.setId("1");
List<Car> cars = new ArrayList<Car>();
Car subaru = new Car();
subaru.setName("Subaru");
subaru.setModel("Imprezza");
cars.add(subaru);
foo.setCar(cars);
Indexing:
IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(foo.getId());
indexQuery.setObject(foo);
//creating mapping
elasticsearchTemplate.putMapping(Person.class);
//indexing document
elasticsearchTemplate.index(indexQuery);
//refresh
elasticsearchTemplate.refresh(Person.class, true);
Searching:
QueryBuilder builder = nestedQuery("car", boolQuery()
.must(termQuery("car.name", "subaru"))
.must(termQuery("car.model", "imprezza")));
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();
List<Person> persons = elasticsearchTemplate.queryForList(searchQuery, Person.class);
You can find more test cases about Nested and Inner Object at Nested Object Tests
You can use IndexQuery for save AND update:
public Serializable saveOrUpdate(Car car) {
return template.index(new IndexQueryBuilder().withObject(car).build());
}