ElasticSearch(七)案例操作
ElasticSearch(七)案例操作
该案例主要完成的功能就是模仿百度实现自动补全+搜索引擎的效果。
-
测试自动补全功能
1、创建一个索引
PUT /product2
{
"mappings": {
"properties": {
"id":{
"type": "integer",
"index": true,
"store": true
},
"productName":{
"type": "completion"
},
"productDesc":{
"type": "text",
"index": true,
"store": true
}
}
}
}
2、添加数据POST /product2/_doc/1
{
"id":1,
"productName":"elasticsearch1",
"productDesc":"elasticsearch1 is good product"
}
POST /product2/_doc/2
{
"id":2,
"productName":"elasticsearch2",
"productDesc":"elasticsearch2 is good product"
}
POST /product2/_doc/3
{
"id":3,
"productName":"elasticsearch3",
"productDesc":"elasticsearch3 is good product"
}
3、自动补全搜索GET /product2/_search
{
"suggest": {
"PREFIX_SUGGESTION": {
"prefix": "elastic",
"completion":{
"field":"productName",
"skip_duplicates":true,
"size":10
}
}
}
}
案例实现
-
创建索引
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.conf配置文件,将其放在与之对应版本的logstash-7.17.0文件夹中的config问价夹中
input {
jdbc {
jdbc_driver_library => "D:\software\Elasticsearch-Windows\7.17.0\anli\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 => ["127.0.0.1:9200"]
index => "news"
document_id => "%{id}"
}
}
-
测试一下新添加的数据,测试自动补齐功能
GET /news/_search
{
"suggest": {
"PREFIX_SUGGESTION": {
"prefix": "中央",
"completion":{
"field":"tags",
"skip_duplicates":true,
"size":10
}
}
}
}
-
ElasticSearch自动补全+搜索引擎功能案例 ---- 项目搭建
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.2</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
ElasticSearch自动补全+搜索引擎功能案例 ---- 编写配置文件application.yml
spring: elasticsearch: uris: 127.0.0.1:9200
-
ElasticSearch自动补全+搜索引擎功能案例 ---- 创建实体类、Repository接口
1、实体类Newsimport lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.elasticsearch.annotations.CompletionField;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.core.suggest.Completion;
/**
* @author huidou
* @date 2022/7/9
*/
@Document(indexName = "news")
@Data
public class News {
@Id
@Field
private Integer id;
@Field
private String title;
@Field
private String content;
@Field
private String url;
@CompletionField
@Transient
private Completion tags;
}
2、Repository接口/**
* @author huidou
* @date 2022/7/9
*/
public interface NewsRepository extends ElasticsearchRepository<News,Integer> {
}
-
ElasticSearch自动补全+搜索引擎功能案例 ---- 自动补全功能
/**
* @author huidou
* @date 2022/7/9
*/
@Service
public class NewsService {
@Autowired
private ElasticsearchRestTemplate template;
// 自动补齐
public List<String> autoSuggest(String keyword) {
// 1.创建补全请求
SuggestBuilder suggestBuilder = new SuggestBuilder();
// 2.构建补全条件
SuggestionBuilder suggestionBuilder = SuggestBuilders.completionSuggestion("tags").prefix(keyword).size(10);
suggestBuilder.addSuggestion("prefix_suggestion", suggestionBuilder);
// 3.发送请求
SearchResponse response = template.suggest(suggestBuilder, IndexCoordinates.of("news"));
// 4.处理结果
List<String> result = response.getSuggest()
.getSuggestion("prefix_suggestion")
.getEntries()
.get(0)
.getOptions()
.stream()
.map(Suggest.Suggestion.Entry.Option::getText)
.map(Text::toString)
.collect(Collectors.toList());
return result;
}
}
/**
* @author huidou
* @date 2022/7/9
*/
@SpringBootTest
public class NewServiceTest {
@Autowired
private NewsService newsService;
@Test
public void testAutoSuggest() {
List<String> stringList = newsService.autoSuggest("中央");
stringList.forEach(System.out::println);
}
}
结果:
中央 中央 中央纪委 中央纪委
-
ElasticSearch自动补全+搜索引擎功能案例 ---- 搜索关键字功能
1、添加Repository接口/**
* @author huidou
* @date 2022/7/9
*/
public interface NewsRepository extends ElasticsearchRepository<News,Integer> {
/**
* 高亮搜索关键字
* @param title
* @param content
* @return
*/
@Highlight(
fields = {
@HighlightField(name = "title"),
@HighlightField(name = "content")
}
)
List<SearchHit<News>> findByTitleMatchesOrContentMatches(String title, String content);
}
2、实现Repository接口的实现类/**
* 查询关键字
* @param keyword
* @return
*/
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;
}
-
ElasticSearch自动补全+搜索引擎功能案例 ---- 创建Controller层
/**
* @author huidou
* @date 2022/7/9
*/
@RestController
public class NewsController {
@Autowired
private NewsService newsService;
@GetMapping("/autoSuggest")
public List<String> autoSuggest(String term) {
// 前端使用jqueryUI,发送的参数默认名为
return newsService.autoSuggest(term);
}
@GetMapping("/highLightSearch")
public List<News> highLightSearch(String term) {
return newsService.highLightSearch(term);
}
}
-
测试自动补全功能
-
添加前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>结果</title>
<link rel="stylesheet" type="text/css" href="css/jquery-ui.min.css"/>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
<script src="js/jquery-2.1.1.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<style>
body {
padding-left: 14px;
padding-top: 14px;
}
ul, li {
list-style: none;
padding: 0;
}
li {
padding-bottom: 16px;
}
a, a:link, a:visited, a:hover, a:active {
text-decoration: none;
}
em {
color: red;
font-style: normal;
}
</style>
</head>
<body>
<div>
<input id="newsTag" class="form-control" style="display: inline; width: 50%;" name="keyword">
<button class="btn btn-primary" onclick="search()">搜索一下</button>
</div>
<hr>
<div>
<ul id="news">
</ul>
</div>
</body>
<script>
$("#newsTag").autocomplete({
source: "/autoSuggest", // 请求路径
delay: 100, //请求延迟
minLength: 1 //最少输入多少字符像服务器发送请求
})
function search() {
var term = $("#newsTag").val();
$.get("/highLightSearch", {term: term}, function (data) {
var str = "";
for (var i = 0; i < data.length; i++) {
var document = data[i];
str += "<li>" +
" <h4>" +
" <a href='" + document.url + "' target='_blank'>" + document.title + "</a>" +
" </h4> " +
" <p>" + document.content + "</p>" +
" </li>";
}
$("#news").html(str);
})
}
</script>
</html>


