Elasticsearch案例

目录

一、创建索引

二、准备数据

三、环境搭建

(1)环境搭建

(2)创建实体类

(3)实现Repository接口

四、实现自动补全功能

五、实现高亮搜索关键字功能

(1)在repository接口中添加高亮搜索关键字方法

(2)service类中调用该方法

六、编写Controller


我们都知道一般在百度的搜索框中搜索的时候,输入框中输的时候下面就会出现一些提示词,比如输入"老",就会出现"老师","老人"之类的词,这就是自动补全,搜索出来的文本有一些是高亮的,特别提示的,这就是高亮功能,本文着重介绍一些这两个功能!(Elasticsearch具体如何实现自动补全,可以参考下博主的这篇文章:elasticsearch的自动补全

一、创建索引

javascript 复制代码
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文件,文件写入以下脚本内容:

javascript 复制代码
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黑窗口,运行命令:

javascript 复制代码
bin\logstash -f config\mysql.conf

测试自动补齐

javascript 复制代码
GET /news/_search
{
  "suggest": {
    "my_suggest": {
      "prefix": "li",
      "completion": {
        "field": "tags",
        "skip_duplicates": true,
        "size": 10
       }
     }
   }
}

三、环境搭建

(1)环境搭建

创建一个springboot项目,引入以下依赖

javascript 复制代码
<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>

编写配置文件

javascript 复制代码
# 连接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)创建实体类

java 复制代码
@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;
}

(3)实现Repository接口

java 复制代码
@Repository
public interface NewsRepository extends ElasticsearchRepository<News, Integer> {
  
}

四、实现自动补全功能

java 复制代码
@Service
public class NewsService {
  @Autowired
  private 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接口中添加高亮搜索关键字方法

java 复制代码
// 高亮搜索关键字
@Highlight(fields = {@HighlightField(name = "title"), @HighlightField(name = "content")})
List<SearchHit<News>> findByTitleMatchesOrContentMatches(String title, String content);

(2)service类中调用该方法

java 复制代码
// 查询关键字
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

java 复制代码
@RestController
public class NewsController {
  @Autowired
  private NewsService newsService;
  
  @GetMapping("/autoSuggest")
  public List<String> autoSuggest(String term){ // 前端使用jqueryUI,发送的参数默认名为term
    return newsService.autoSuggest(term);
   }
  
  @GetMapping("/highLightSearch")
  public List<News> highLightSearch(String term){
    return newsService.highLightSearch(term);
   }
}

因为本项目是前后端分离,所以测试的话直接调用接口看他是不是返回对应的数据即可!

相关推荐
AI人工智能+电脑小能手1 分钟前
大白话说Java设计模式-23-桥接模式(源码剖析篇)
java·设计模式·jdbc·桥接模式·源码分析·awt·java logging
long31610 分钟前
枚举(Enums)
java·开发语言·数据库
墨雨晨曦8831 分钟前
2026/08/15 spring AI学习总结
java·tomcat
wno7041 小时前
Spring Boot JdbcTemplate配置Druid多数据源
java·spring boot·后端
聊浮游1 小时前
JAVA2026最新全套学习资料、学习路线
java·开发语言·jvm·mysql·spring·maven·idea
Elasticsearch1 小时前
什么是上下文工程?
elasticsearch
MacroZheng1 小时前
完美替代 Navicat!这款内置 AI 的数据库工具,太香了!
java·后端·mysql
月华路2 小时前
Guava 图数据结构 graph 从基础概念到原理分析
java·数据结构·guava·图搜索
SamDeepThinking2 小时前
从REST到gRPC,一个API选型的思考框架
java·后端·程序员
Zane19942 小时前
接口都能写默认实现了,为什么还需要抽象类
java·后端