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、实体类News
import 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>

  • 测试前端页面的实现




全部评论

相关推荐

点赞 评论 收藏
分享
東大沒有派對:这是好事啊(峰哥脸
我的秋招日记
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务