Elasticsearch案例
目录
一、创建索引
二、准备数据
三、环境搭建
(1)环境搭建
(2)创建实体类
(3)实现Repository接口
四、实现自动补全功能
五、实现高亮搜索关键字功能
(1)在repository接口中添加高亮搜索关键字方法
(2)service类中调用该方法
六、编写Controller
我们都知道一般在百度的搜索框中搜索的时候,输入框中输的时候下面就会出现一些提示词,比如输入“老”,就会出现“老师”,“老人”之类的词,这就是自动补全,搜索出来的文本有一些是高亮的,特别提示的,这就是高亮功能,本文着重介绍一些这两个功能!(Elasticsearch具体如何实现自动补全,可以参考下博主的这篇文章:elasticsearch的自动补全)
一、创建索引
PUT /news
{"settings": {"number_of_shards": 5,"number_of_replicas": 1,"analysis": {"analyzer": {"ik_pinyin": {"tokenizer": "ik_smart","filter": "pinyin_filter"},"tag_pinyin": {"tokenizer": "keyword","filter": "pinyin_filter"}},"filter": {"pinyin_filter": {"type": "pinyin","keep_joined_full_pinyin": true,"keep_original": true,"remove_duplicated_term": true}}}},"mappings": {"properties": {"id": {"type": "integer","index": true},"title": {"type": "text","index": true,"analyzer": "ik_pinyin","search_analyzer": "ik_smart"},"content": {"type": "text","index": true,"analyzer": "ik_pinyin","search_analyzer": "ik_smart"},"url": {"type": "keyword","index": true},"tags": {"type": "completion","analyzer": "tag_pinyin","search_analyzer": "tag_pinyin"}}}
}
二、准备数据
将MySQL中的数据同步到elasticsearch中,我使用的是logstash,注意版本一定要和elasticsearch一致!压缩包我放到我的主页资源列表了!
在logstash解压路径下的/config中创建mysql.conf文件,文件写入以下脚本内容:
input {jdbc {jdbc_driver_library => "C:\案例\mysql-connector-java-5.1.37-bin.jar"jdbc_driver_class => "com.mysql.jdbc.Driver"jdbc_connection_string => "jdbc:mysql:///news"jdbc_user => "root"jdbc_password => "root"schedule => "* * * * *"jdbc_default_timezone => "Asia/Shanghai"statement => "SELECT * FROM news;"}
}filter {mutate {split => {"tags" => ","}}
}output {elasticsearch {hosts => ["http://192.168.66.147:9200","http://192.168.66.147:9201","http://192.168.66.147:9202"]index => "news"document_id => "%{id}"}
}
在解压路径下打开cmd黑窗口,运行命令:
bin\logstash -f config\mysql.conf
测试自动补齐
GET /news/_search
{"suggest": {"my_suggest": {"prefix": "li","completion": {"field": "tags","skip_duplicates": true,"size": 10}}}
}
三、环境搭建
(1)环境搭建
创建一个springboot项目,引入以下依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>
编写配置文件
# 连接elasticsearch
spring:elasticsearch:uris: 192.168.0.187:9200,192.168.0.187:9201,192.168.0.187:9202# 日志格式
logging:pattern:console: '%d{HH:mm:ss.SSS} %clr(%-5level) --- [%-15thread] %cyan(%-50logger{50}):%msg%n'
(2)创建实体类
@Document(indexName = "news")
@Data
public class News {@Id@Fieldprivate Integer id;@Fieldprivate String title;@Fieldprivate String content;@Fieldprivate String url;@CompletionField@Transientprivate Completion tags;
}
(3)实现Repository接口
@Repository
public interface NewsRepository extends ElasticsearchRepository<News, Integer> {}
四、实现自动补全功能
@Service
public class NewsService {@Autowiredprivate ElasticsearchClient client;// 自动补齐public List<String> autoSuggest(String keyword) throws IOException {// 1.自动补齐查询条件Suggester suggester = Suggester.of(s -> s.suggesters("prefix_suggestion", FieldSuggester.of(fs -> fs.completion(cs -> cs.skipDuplicates(true).size(10).field("tags")))).text(keyword));// 2.自动补齐查询SearchResponse<Map> response = client.search(s -> s.index("news").suggest(suggester), Map.class);// 3.处理查询结果Map resultMap = response.suggest();List<Suggestion> suggestionList = (List) resultMap.get("prefix_suggestion");Suggestion suggestion = suggestionList.get(0);List<CompletionSuggestOption> resultList = suggestion.completion().options();List<String> result = new ArrayList<>();for (CompletionSuggestOption completionSuggestOption : resultList) {String text = completionSuggestOption.text();result.add(text);}return result;}
}
五、实现高亮搜索关键字功能
(1)在repository接口中添加高亮搜索关键字方法
// 高亮搜索关键字
@Highlight(fields = {@HighlightField(name = "title"), @HighlightField(name = "content")})
List<SearchHit<News>> findByTitleMatchesOrContentMatches(String title, String content);
(2)service类中调用该方法
// 查询关键字
public List<News> highLightSearch(String keyword){List<SearchHit<News>> result = repository.findByTitleMatchesOrContentMatches(keyword, keyword);// 处理结果,封装为News类型的集合List<News> newsList = new ArrayList();for (SearchHit<News> newsSearchHit : result) {News news = newsSearchHit.getContent();// 高亮字段Map<String, List<String>> highlightFields = newsSearchHit.getHighlightFields();if (highlightFields.get("title") != null){news.setTitle(highlightFields.get("title").get(0));}if (highlightFields.get("content") != null){news.setContent(highlightFields.get("content").get(0));}newsList.add(news);}return newsList;
}
六、编写Controller
@RestController
public class NewsController {@Autowiredprivate NewsService newsService;@GetMapping("/autoSuggest")public List<String> autoSuggest(String term){ // 前端使用jqueryUI,发送的参数默认名为termreturn newsService.autoSuggest(term);}@GetMapping("/highLightSearch")public List<News> highLightSearch(String term){return newsService.highLightSearch(term);}
}
因为本项目是前后端分离,所以测试的话直接调用接口看他是不是返回对应的数据即可!