问答平台(6),Spring整合Elasticsearch

引入依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

配置 Elasticsearch

1
2
3
# ElasticsearchProperties
spring.data.elasticsearch.cluster-name=nowcoder
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300(TCP

解决 netty 启动冲突问题

  • CommunityApplication: 修改
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @SpringBootApplication
    public class CommunityApplication {

    @PostConstruct
    public void init() {
    // 解决netty启动冲突问题
    // see Netty4Utils.setAvailableProcessors()
    System.setProperty("es.set.netty.runtime.available.processors", "false");
    }

    public static void main(String[] args) {
    SpringApplication.run(CommunityApplication.class, args);
    }

    }

Spring Data Elasticsearch

1
2
- ElasticsearchTemplate
- ElasticsearchRepository

实体类与ES映射(自动)

  • entity -> DiscussPost
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    @Document(indexName = "discusspost", type = "_doc", shards = 6, replicas = 3)
    public class DiscussPost {

    @Id
    private int id;

    @Field(type = FieldType.Integer)
    private int userId;

    // 互联网校招
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String title;

    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String content;

    @Field(type = FieldType.Integer)
    private int type;

    @Field(type = FieldType.Integer)
    private int status;

    @Field(type = FieldType.Date)
    private Date createTime;

    @Field(type = FieldType.Integer)
    private int commentCount;

    @Field(type = FieldType.Double)
    private double score;
    }
  • dao -> elasticsearch -> DiscussPostRepository
    1
    2
    3
    4
    @Repository
    public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost, Integer> {

    }

测试类

  • ElasticsearchTests: 新增
    1
    2
    3
    4
    5
    6
    7
    8
    9
    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @ContextConfiguration(classes = CommunityApplication.class)
    public class ElasticsearchTests {

    @Autowired
    private DiscussPostMapper discussPostMapper;

    @Autowired
    private DiscussPostRepository discussPostRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Test
    public void testInsert() {
    discussPostRepository.save(discussPostMapper.selectDiscussPostById(241));
    discussPostRepository.save(discussPostMapper.selectDiscussPostById(242));
    discussPostRepository.save(discussPostMapper.selectDiscussPostById(243));
    }

    @Test
    public void testInsertList() {
    discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(101, 0, 100));
    discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(102, 0, 100));
    discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(103, 0, 100));
    discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(111, 0, 100));
    discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(112, 0, 100));
    discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(131, 0, 100));
    discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(132, 0, 100));
    discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(133, 0, 100));
    discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(134, 0, 100));
    }

    @Test
    public void testUpdate() {
    DiscussPost post = discussPostMapper.selectDiscussPostById(231);
    post.setContent("我是新人,使劲灌水.");
    discussPostRepository.save(post);
    }

    @Test
    public void testDelete() {
    // discussPostRepository.deleteById(231);
    discussPostRepository.deleteAll();
    }

    @Test
    public void testSearchByRepository() {
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
    .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))
    .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
    .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
    .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
    .withPageable(PageRequest.of(0, 10))
    .withHighlightFields(
    new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
    new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")
    ).build();

    // elasticsearchTemplate.queryForPage(searchQuery, class, SearchResultMapper);
    // 底层获取得到了高亮显示的值,但是没有返回.

    Page<DiscussPost> page = discussPostRepository.search(searchQuery);
    System.out.println(page.getTotalElements());
    System.out.println(page.getTotalPages());
    System.out.println(page.getNumber());
    System.out.println(page.getSize());
    for (DiscussPost post : page) {
    System.out.println(post);
    }
    }

    @Test
    public void testSearchByTemplate() {
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
    .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))
    .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
    .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
    .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
    .withPageable(PageRequest.of(0, 10))
    .withHighlightFields(
    new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
    new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")
    ).build();

    Page<DiscussPost> page = elasticsearchTemplate.queryForPage(searchQuery, DiscussPost.class, new SearchResultMapper() {
    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) {
    SearchHits hits = response.getHits();
    if (hits.getTotalHits() <= 0) {
    return null;
    }

    List<DiscussPost> list = new ArrayList<>();
    for (SearchHit hit : hits) {
    DiscussPost post = new DiscussPost();

    String id = hit.getSourceAsMap().get("id").toString();
    post.setId(Integer.valueOf(id));

    String userId = hit.getSourceAsMap().get("userId").toString();
    post.setUserId(Integer.valueOf(userId));

    String title = hit.getSourceAsMap().get("title").toString();
    post.setTitle(title);

    String content = hit.getSourceAsMap().get("content").toString();
    post.setContent(content);

    String status = hit.getSourceAsMap().get("status").toString();
    post.setStatus(Integer.valueOf(status));

    String createTime = hit.getSourceAsMap().get("createTime").toString();
    post.setCreateTime(new Date(Long.valueOf(createTime)));

    String commentCount = hit.getSourceAsMap().get("commentCount").toString();
    post.setCommentCount(Integer.valueOf(commentCount));

    // 处理高亮显示的结果
    HighlightField titleField = hit.getHighlightFields().get("title");
    if (titleField != null) {
    post.setTitle(titleField.getFragments()[0].toString());
    }

    HighlightField contentField = hit.getHighlightFields().get("content");
    if (contentField != null) {
    post.setContent(contentField.getFragments()[0].toString());
    }

    list.add(post);
    }

    return new AggregatedPageImpl(list, pageable,
    hits.getTotalHits() , response.getAggregations(), response.getScrollId(), hits.getMaxScore());
    }
    });

    System.out.println(page.getTotalElements());
    System.out.println(page.getTotalPages());
    System.out.println(page.getNumber());
    System.out.println(page.getSize());
    for (DiscussPost post : page) {
    System.out.println(post);
    }
    }
    }

结果展示

分词加标签-图示


问答平台(6),Spring整合Elasticsearch
https://lcf163.github.io/2020/06/07/问答平台(6),Spring整合Elasticsearch/
作者
乘风的小站
发布于
2020年6月7日
许可协议