В этой статье я постараюсь дать вам простое представление о том, как использовать Elastic Search в проекте Java. Поскольку Spring Boot — это самый простой и быстрый способ начать наш проект, я решил его использовать. Кроме того, мы будем активно использовать положительные отзывы Repository от любимых Spring Data.
Давайте начнем с установки Elastic Search на нашу машину и запускаем наш эластичный сервер в первый раз.
Я захожу вastic-folder \ bin и запускаюasticsearch.bat (да, я использую Windows), но не повезло. Я получаю это:
«Произошла ошибка во время инициализации ВМ
Не удалось зарезервировать достаточно места для кучи объектов
Ошибка: не удалось создать виртуальную машину Java.
Ошибка: произошло фатальное исключение. Программа будет закрыта.»
Какое отличное начало!
В моей папке bin есть файл «asticsearch.in.bat ». Я установил ES_MAX_MEM = 1g на ES_MAX_MEM = 512 МБ и вуаля это исправлено.
После этого я запускаю новый сервер без проблем.
Теперь пришло время определить документ, который мы будем индексировать в упругом поиске. Предположим, у нас есть информация о фильме для индексации. Наша модель довольно проста. Фильм имеет название, рейтинг и жанр. Я выбрал «astic_sample »в качестве имени индекса, которое звучит хорошо в качестве имени базы данных, и« movie »в качестве типа, который подходит для имени таблицы, если мы думаем в терминах реляционной базы данных. Ничего особенного в модели, как вы можете видеть.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
@Document(indexName = "elastic_sample", type = "movie")public class Movie { @Id private String id; private String name; @Field(type = FieldType.Nested) private List < Genre > genre; private Double rating; public Double getRating() { return rating; } public void setRating(Double rating) { this.rating = rating; } public void setId(String id) { this.id = id; } public List < Genre > getGenre() { return genre; } public void setGenre(List < Genre > genre) { this.genre = genre; } public String getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Movie{" + "id=" + id + ", name='" + name + '\'' + ", genre=" + genre + ", rating=" + rating + '}'; }} |
Для тех, кому интересно, что это за жанр, вот оно. Просто POJO.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public class Genre { private String name; public Genre() { } public Genre(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return "Genre{" + "name='" + name + '\'' + '}'; } public void setName(String name) { this.name = name; }} |
Сейчас не время создавать слой DAO, чтобы мы могли сохранять и загружать наш документ на наш сервер эластичного поиска. Наш репозиторий расширяет классический ElasticserchRepository (не знаю, почему это поиск, а не поиск). Как вы, наверное, знаете, Spring Data может запрашивать одно или несколько полей с помощью этих предопределенных методов, где мы используем имена наших полей. findByName будет искать в поле имени, findByRating будет искать в поле рейтинга и так далее. Более того, благодаря Spring Data нам не нужно писать для него реализацию, мы просто помещаем имена методов в интерфейс, и на этом все.
|
1
2
3
4
5
|
public interface MovieRepository extends ElasticsearchRepository < Movie, Long > { public List < Movie > findByName(String name); public List < Movie> findByRatingBetween(Double beginning, Double end);} |
Наш уровень DAO будет вызываться уровнем службы:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
@Servicepublic class MovieService { @Autowired private MovieRepository repository; public List < Movie > getByName(String name) { return repository.findByName(name); } public List < Movie > getByRatingInterval(Double beginning, Double end) { return repository.findByRatingBetween(beginning, end); } public void addMovie(Movie movie) { repository.save(movie); }} |
Вот основной класс, который мы будем использовать для запуска нашего приложения. EnableAutoConfiguration автоматически настроит все, что распознает в нашем пути к классам. ComponentScan будет сканировать аннотации Spring в главном каталоге Class.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
@Configuration@EnableAutoConfiguration@ComponentScanpublic class BootElastic implements CommandLineRunner { @Autowired private MovieService movieService; private static final Logger logger = LoggerFactory.getLogger(BootElastic.class);// add star wars and// princess bride as a movie// to elastic search private void addSomeMovies() { Movie starWars = getFirstMovie(); movieService.addMovie(starWars); Movie princessBride = getSecondMovie(); movieService.addMovie(princessBride); } private Movie getSecondMovie() { Movie secondMovie = new Movie(); secondMovie.setId("2"); secondMovie.setRating(8.4d); secondMovie.setName("The Princess Bride"); List < Genre > princessPrideGenre = new ArrayList < Genre >(); princessPrideGenre.add(new Genre("ACTION")); princessPrideGenre.add(new Genre("ROMANCE")); secondMovie.setGenre(princessPrideGenre); return secondMovie; } private Movie getFirstMovie() { Movie firstMovie = new Movie(); firstMovie.setId("1"); firstMovie.setRating(9.6d); firstMovie.setName("Star Wars"); List < Genre > starWarsGenre = new ArrayList < Genre >(); starWarsGenre.add(new Genre("ACTION")); starWarsGenre.add(new Genre("SCI_FI")); firstMovie.setGenre(starWarsGenre); return firstMovie; } public void run(String... args) throws Exception { addSomeMovies(); // We indexed star wars and pricess bride to our movie // listing in elastic search //Lets query if we have a movie with Star Wars as name List < Movie > starWarsNameQuery = movieService.getByName("Star Wars"); logger.info("Content of star wars name query is {}", starWarsNameQuery); //Lets query if we have a movie with The Princess Bride as name List < Movie > brideQuery = movieService.getByName("The Princess Bride"); logger.info("Content of princess bride name query is {}", brideQuery); //Lets query if we have a movie with rating between 6 and 9 List < Movie > byRatingInterval = movieService.getByRatingInterval(6d, 9d); logger.info("Content of Rating Interval query is {}", byRatingInterval); } public static void main(String[] args) throws Exception { SpringApplication.run(BootElastic.class, args); }} |
Если мы запустим его, результат будет:
|
1
2
3
|
015-02-28 18:26:12.368 INFO 3616 --- [ main] main.BootElastic: Content of star wars name query is [Movie{id=1, name='Star Wars', genre=[Genre{name='ACTION'}, Genre{name='SCI_FI'}], rating=9.6}]2015-02-28 18:26:12.373 INFO 3616 --- [ main] main.BootElastic: Content of princess bride name query is [Movie{id=2, name='The Princess Bride', genre=[Genre{name='ACTION'}, Genre{name='ROMANCE'}], rating=8.4}]2015-02-28 18:26:12.384 INFO 3616 --- [ main] main.BootElastic: Content of Rating Interval query is [Movie{id=2, name='The Princess Bride', genre=[Genre{name='ACTION'}, Genre{name='ROMANCE'}], rating=8.4}] |
Как видно из интервала запроса, извлекается только принцесса-невеста. Мы не сделали никакой конфигурации, верно? Это необычно. Я должен поделиться с вами огромным файлом конфигурации:
|
1
2
3
|
spring.data.elasticsearch.cluster-nodes=localhost:9300 # if spring data repository support is enabledspring.data.elasticsearch.repositories.enabled=true |
Обычно вы используете порт 9200 при запросе к вашему эластичному серверу. Но когда мы программно достигаем его, мы используем 9300. Если у вас более одного узла, вы должны разделить их запятой и использовать 9301, 9302 и т. Д. В качестве номеров портов. Наш файл POM тоже не удивителен. Просто эластичный стартовый пом и мы готовы к работе.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <groupid>caught.co.nr</groupid> <artifactid>boot-elastic-sample</artifactid> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <!-- Inherit defaults from Spring Boot --> <parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>1.2.2.RELEASE</version> </parent> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-data-elasticsearch</artifactid> </dependency> </dependencies> <!-- Needed for fat jar --> <build> <plugins> <plugin> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-maven-plugin</artifactid> </plugin> </plugins> </build></project> |
Как вы видите, благодаря Spring Boot and Data довольно легко работать с эластичным поиском. Давайте посмотрим, что мы проиндексировали с сервера API также. Я буду использовать Sense — хромированный плагин для упругих команд.
Вот результат JSON:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
{ "took": 2, "timed_out": false, "_shards": { "total": 1, "successful": 1, "failed": 0 }, "hits": { "total": 2, "max_score": 1, "hits": [ { "_index": "elastic_sample", "_type": "movie", "_id": "1", "_score": 1, "_source": { "id": 1, "name": "Star Wars", "genre": [ { "name": "ACTION" }, { "name": "SCI_FI" } ] } }, { "_index": "elastic_sample", "_type": "movie", "_id": "2", "_score": 1, "_source": { "id": 2, "name": "The Princess Bride", "genre": [ { "name": "ACTION" }, { "name": "ROMANCE" } ] } } ] }} |
- Вы можете проверить весь проект в GitHub .
| Ссылка: | Начните первый упругий поиск на java с пружинной загрузкой и функциями данных от нашего партнера JCG Сезина Карли в пойманном Somewhere In Time = true; блог. |

