Distributed index for SpringBoot applications

  elasticsearch, springboot

SpringBoot application series articles

Order

This article focuses on how to use elasticsearch in SpringBoot. Elasticsearch is an index service from its root, but at the high end, it is a distributed real-time file storage and a distributed real-time analysis search engine.

Prepare es

For details, seeDocker environment builds elasticsearchThis one.

New project

图片描述

application.properties

spring.data.elasticsearch.repositories.enabled=true
spring.data.elasticsearch.cluster-name=cn-out-of-box
spring.data.elasticsearch.cluster-nodes=192.168.99.100:9300

Model

@Document(indexName = "post", type = "post", shards = 1, replicas = 0)
public class Post {
    @Id
    private String id;

    private String title;

    private Double rating;

    @Field(type= FieldType.Nested)
    private List<Tag> tags;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<Tag> getTags() {
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }

    public Double getRating() {
        return rating;
    }

    public void setRating(Double rating) {
        this.rating = rating;
    }
}

Embedded object

public class Tag {
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

repository

public interface PostRepository extends ElasticsearchRepository<Post, String> {

    Page<Post> findByTagsName(String name, Pageable pageable);

    List<Post> findByRatingBetween(Double beginning, Double end);

}

Service layer

@Service
public class PostService {

    @Autowired
    PostRepository postRepository;

    public Post save(Post post){
        postRepository.save(post);
        return post;
    }

    public Post findOne(String id) {
        return postRepository.findOne(id);
    }

    public Iterable<Post> findAll() {
        return postRepository.findAll();
    }

    public Page<Post> findByTagsName(String tagName, PageRequest pageRequest) {
        return postRepository.findByTagsName(tagName, pageRequest);
    }

    List<Post> findByRatingBetween(Double beginning, Double end){
        return postRepository.findByRatingBetween(beginning,end);
    }
}

Test

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = EsdemoApplication.class)
public class EsdemoApplicationTests {

    @Autowired
    private PostService postService;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Before
    public void before() {
        elasticsearchTemplate.deleteIndex(Post.class);
        elasticsearchTemplate.createIndex(Post.class);
        elasticsearchTemplate.putMapping(Post.class);
        elasticsearchTemplate.refresh(Post.class, true);
    }

    @Test
    public void testSave() throws Exception {
        Tag tag = new Tag();
        tag.setId("1");
        tag.setName("tech");
        Tag tag2 = new Tag();
        tag2.setId("2");
        tag2.setName("elasticsearch");

        Post post = new Post();
        post.setId("1");
        post.setTitle("Bigining with spring boot application and elasticsearch");
        post.setRating(9.5);
        post.setTags(Arrays.asList(tag, tag2));
        postService.save(post);

        assertThat(post.getId(), notNullValue());

        Post post2 = new Post();
        post2.setId("2");
        post2.setTitle("Bigining with spring boot application");
        post2.setTags(Arrays.asList(tag));
        post2.setRating(7.5);
        postService.save(post2);
        assertThat(post2.getId(), notNullValue());
    }

    @Test //tag必须不是nested的
    public void testFindByTagsName() throws Exception {
        Tag tag = new Tag();
        tag.setId("1");
        tag.setName("tech");
        Tag tag2 = new Tag();
        tag2.setId("2");
        tag2.setName("elasticsearch");

        Post post = new Post();
        post.setId("1");
        post.setTitle("Bigining with spring boot application and elasticsearch");
        post.setRating(9.4);
        post.setTags(Arrays.asList(tag, tag2));
        postService.save(post);



        Post post2 = new Post();
        post2.setId("1");
        post2.setTitle("Bigining with spring boot application");
        post2.setTags(Arrays.asList(tag));
        post2.setRating(9.6);
        postService.save(post2);

        Page<Post> posts  = postService.findByTagsName("tech", new PageRequest(0,10));
        Page<Post> posts2  = postService.findByTagsName("tech", new PageRequest(0,10));
        Page<Post> posts3  = postService.findByTagsName("maz", new PageRequest(0,10));


        assertThat(posts.getTotalElements(), is(1L));
        assertThat(posts2.getTotalElements(), is(1L));
        assertThat(posts3.getTotalElements(), is(0L));
    }

}

Save screenshot
图片描述

Pit

  • NoNodeAvailableException
org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: []

The cluster-name specified in the application is inconsistent with the cluster.name in the cluster.

References