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);
   }
}

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

相关推荐
晴子呀2 分钟前
Java基础知识扫盲
java·开发语言
不惑_21 分钟前
缓存技巧 · Spring Cache && Caffeine 高性能缓存库
java·spring·缓存
六月的雨__1 小时前
自驾游拼团系统小程序的设计
java·sql·学习·小程序
Tinalee-电商API接口呀1 小时前
【经验分享】电商api接口——各类商品数据一键获取
java·大数据·开发语言·python·json·产品运营·html5
2401_857638031 小时前
Spring Boot框架在高校心理辅导中的实践
java·spring boot·后端
BUG指挥官1 小时前
7种限流算法打开新方式
java·redis·算法·spring cloud
我不会起名字呀2 小时前
c/c++八股文
java·c语言·c++
户伟伟2 小时前
设计模式六大原则:面向对象设计的核心
java·后端·设计模式
神的孩子都在歌唱2 小时前
个人导航网站介绍和部署
java·开发语言·开源软件