elasticsearch 查看分词结果_第4天 分布式搜索引擎ElasticSearch

本文详细介绍了ElasticSearch的特性、部署启动、使用Postman调用REST API,以及Head插件的安装与使用。讲解了IK分词器的安装与测试,展示了如何通过Logstash实现数据库与ElasticSearch的同步。同时,文章还涵盖了搜索微服务的开发流程,包括创建模块、添加文章到索引库、搜索文章等,并总结了ElasticSearch面试常见问题。
摘要由CSDN通过智能技术生成

3fde00470d573b398ebfa6acaf8be5d9.png

dian上篇:

Gavin:第 3 天 文档型数据库MongoDB​zhuanlan.zhihu.com
5671687125c8794a4702e555c84041da.png

一、ElasticSearch简介

1、什么是ElasticSearch

Elasticsearch是一个实时的分布式搜索和分析引擎。它可以帮助你用前所未有的速 度去处理大规模数据。ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分 布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发 的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用 于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

2、ElasticSearch特点

(1)可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公 司;也可以运行在单机上

(2)将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;

(3)开箱即用的,部署简单

(4)全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理

3、 ElasticSearch体系结构

下表是Elasticsearch与MySQL数据库逻辑结构概念的对比

c6bf978be49ff9144dbb203b8be02042.png

二、走进ElasticSearch

1、 ElasticSearch部署与启动

安装教程:https://zhuanlan.zhihu.com/p/134104899

访问:http://spark2.x:9200/

c3b38ef123a6fc6de992692ddc79a3da.png

2、Postman调用RestAPI

新建索引 (创建索引库)

例如我们要创建一个叫articleindex的索引 ,就以put方式提交

提交url:http://spark2.x:9200/articleindex01/

873bf93dbbe55a4e272aee9e68aaee1d.png

新建文档

以post方式提交 :http://spark2.x:9200/articleindex01/article01

1bee264b583930b8750d992226d23563.png

打印输出的json数据:

{
    "_index": "articleindex01",
    "_type": "article01 ",
    "_id": "gKkw5XQBjtst7OKrbi13",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

查询全部文档

查询某索引某类型的全部数据,以get方式请求

http://spark2.x:9200/articleindex01/article01/_search

8b32bf4d4ae62e43daf18e23c2712601.png

修改文档

以put形式提交以下地址:

http://spark2.x:9200/articleindex01/article01/fakb5XQBjtst7OKr-y3A

18cf240c68beec644ab44f5bf75a0f4c.png

另一种情况

如果我们在地址中的ID不存在,则会创建新文档

以put形式提交以下地址:http://spark2.x:9200/articleindex01/article01/1

0211368f70a839b828592e5311625579.png

基本匹配查询

根据某列进行查询 get方式提交下列地址:

http://192.168.184.134:9200/articleindex01/article01/_search?q=title:十次方课程

好给力

以上为按标题查询,返回结果如下:

{
    "took":10,
    "timed_out":false,
    "_shards":{
        "total":5,
        "successful":5,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":1,
        "max_score":2.0649285,
        "hits":[
            {
                "_index":"articleindex",
                "_type":"article",
                "_id":"1",
                "_score":2.0649285,
                "_source":{
                    "title":"十次方课程好给力",
                    "content":"知识点很多"
                }
            }

模糊查询

我们可以用*代表任意字符:

http://spark2.x:9200/articleindex01/article01/_search?q=title:*s*

删除文档

根据ID删除文档,删除ID为1的文档 DELETE方式提交

http://spark2.x:9200/articleindex01/article01/1

返回结果如下:

{
    "found":true,
    "_index":"articleindex",
    "_type":"article",
    "_id":"1",
    "_version":2,
    "result":"deleted",
    "_shards":{
        "total":2,
        "successful":1,
        "failed":0
    }
}

再次查看全部是否还存在此记录

3、Head插件的安装与使用

(1)Head插件安装

如果都是通过rest请求的方式使用Elasticsearch,未免太过麻烦,而且也不够人性化。我们一般都会使用图形化界面来实现Elasticsearch的日常管理,最常用的就是Head插件

下载head插件:https://github.com/mobz/elasticsearch-head

(2)解压到任意目录

但是要和elasticsearch的安装目录区别开

51f2864ab6a86deebd3cb7f877d8ef4b.png

(3)安装node js ,安装cnpm

D:javanojselasticsearch-head-master>npm install -g cnpm --registry=https://registry.npm.taobao.org

npm WARN deprecated har-validator@5.1.5: this library is no longer supported
C:UsersmrmanAppDataRoamingnpmcnpm -> C:UsersmrmanAppDataRoamingnpmnode_modulescnpmbincnpm
+ cnpm@6.1.1
added 685 packages in 47.634s

(4)安装node js

07129c7ce67f686d918d06fec7166b14.png

下载地址:链接:https://pan.baidu.com/s/11fOQxZVAcRfSP2OnKXUZAg

提取码:72o3

一直下一步即可

d35fe760a9ac6cecc8c1c9619e56a707.png

将grunt安装为全局命令 。Grunt是基于Node.js的项目构建工具。它可以自动运行你所 设定的任务 ,在cmd窗口执行:

npm install ‐g grunt‐cli

如图所示:

ad2abf21b5ce63181a2926256864043b.png

(5)安装依赖

D:javanojselasticsearch-head-master>cnpm install

如图所示:

8165b3191e047d05e0f9fea9b5f2c06b.png

b5529e1741ad0742ea67900b15b59857.png

(6)进入head目录启动head,在命令提示符下输入命令

D:javanojselasticsearch-head-master>grunt server

如图所示:

7120a0a144ae897f0bfe4efbfbdf9051.png

访问:http://localhost:9100

b3d0e5e05500f47f3beeee8cf6b65ba1.png

解决es跨域访问问题

98b9638b049583b31f56cab9a39e1d36.png

我们这时需要修改elasticsearch的配置,让其允许跨域访问。

修改elasticsearch配置文件:elasticsearch.yml,增加以下两句命令:

elasticsearch-6.3.1/config

[root@spark2 config]# pwd
/usr/local/etc/hadoop/module/elasticsearch-6.3.1/config

[root@spark2 config]# vim elasticsearch.yml 

//增加以下两句命令
http.cors.enabled: true 
http.cors.allow‐origin: "*"

4b36823239aa43ecb3025187102f7052.png

重新启动elasticsearch

连接后,如图所示:

4eb3a9c6c456833179c2fdae40452221.png

3、head插件的安装和使用

(1)创建索引库

1a4c0bf6acad29a433b0084e889b2ad2.png

a60c53922ee38f77721b7966050e1fbc.png

新建或修改文档

在复合查询中提交地址,输入内容,提交方式为PUT ,点击数据浏览 ,点击要查询的索引名称,右侧窗格中显示文档信息

efd091de242c7bd05e36c9f6a942b902.png
添加数据

点击文档信息:

2a37e2d5ea3fefef09736f5477f6065e.png
浏览数据

修改文档

在复合查询中提交地址,输入内容,提交方式为PUT

http://spark2.x:9200/tensquare_elasticsearch/article/3/

995c2a31a6ab02604172977d368133ae.png

点击数据浏览 ,点击要查询的索引名称,右侧窗格中显示文档信息

e6780ac01753f27636cb6a06e95f4ad9.png

点击文档信息:

0722586a459a32199ac36b3a697b3454.png

删除文档

a013bbf85d9b26d92e77692404d84ec2.png

4、ik分词器的使用

(1)什么是IK分词器

IK分词是一款国人开发的相对简单的中文分词器。虽然开发者自2012年之后就不在维护 了,但在工程应用中IK算是比较流行的一款!我们今天就介绍一下IK中文分词器的使用。

(2)IK分词器安装

下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases 下载5.6.8版

链接:https://pan.baidu.com/s/1RjNkvL70Ak2ZA9J8UUY61A

提取码:ep4p

  • 先将其解压,将解压后的elasticsearch文件夹重命名文件夹为ik
  • 将ik文件夹拷贝到elasticsearch/plugins 目录下
  • 重新启动,即可加载IK分词器

由于下载elasticsearch-analysis-ik-6.3.1.zip 的后缀名是zip格式,解压需要注意:

//解压命令“jar xvf 压缩包”
[root@spark2 plugins]# jar xvf elasticsearch-analysis-ik-6.3.1.zip 
  created: config/
 inflated: config/extra_single_word_low_freq.dic
 inflated: config/quantifier.dic
 inflated: config/extra_stopword.dic
 inflated: config/extra_main.dic
 inflated: config/preposition.dic
 inflated: config/extra_single_word_full.dic
 inflated: config/extra_single_word.dic
 inflated: config/IKAnalyzer.cfg.xml
 inflated: config/surname.dic
 inflated: config/main.dic
 inflated: config/suffix.dic
 inflated: config/stopword.dic
 inflated: plugin-descriptor.properties
 inflated: plugin-security.policy
 inflated: elasticsearch-analysis-ik-6.3.1.jar
 inflated: httpclient-4.5.2.jar
 inflated: httpcore-4.4.4.jar
 inflated: commons-logging-1.2.jar
 inflated: commons-codec-1.9.jar

//解压ok
[root@spark2 plugins]# ll
total 5828
-rw-r--r--. 1 root root  263965 May  6  2018 commons-codec-1.9.jar
-rw-r--r--. 1 root root   61829 May  6  2018 commons-logging-1.2.jar
drwxr-xr-x. 2 root root    4096 May  6  2018 config
-rw-r--r--. 1 root root   52399 Jul 18  2018 elasticsearch-analysis-ik-6.3.1.jar
-rw-r--r--. 1 root root 4502496 Oct  2 09:53 elasticsearch-analysis-ik-6.3.1.zip
-rw-r--r--. 1 root root  736658 May  6  2018 httpclient-4.5.2.jar
-rw-r--r--. 1 root root  326724 May  6  2018 httpcore-4.4.4.jar
-rw-r--r--. 1 root root    1805 Jul 18  2018 plugin-descriptor.properties
-rw-r--r--. 1 root root     125 Jul 18  2018 plugin-security.policy
[root@spark2 plugins]# 

将ik文件夹拷贝到elasticsearch/plugins 目录下

910a3916dc9da9e4d786ddeee396875f.png

重新启动,即可加载IK分词器

3c895b6702774b885ff11dc46b223616.png

IK分词器测试

IK提供了两个分词算法ik_smart 和 ik_max_word ,其中 ik_smart 为最少切分,ik_max_word为最细粒度划分

我们分别来试一下

(1)最小切分:在浏览器地址栏输入地址

http://spark2.x:9200/_analyze?analyzer=ik_smart&pretty=true&text=我是程序员

输出的结果为:

{
    "tokens":[
        {
            "token":"我",
            "start_offset":0,
            "end_offset":1,
            "type":"CN_CHAR",
            "position":0
        },
        {
            "token":"是",
            "start_offset":1,
            "end_offset":2,
            "type":"CN_CHAR",
            "position":1
        },
        {
            "token":"程序员",
            "start_offset":2,
            "end_offset":5,
            "type":"CN_WORD",
            "position":2
        }
    ]
}

(2)最细切分:在浏览器地址栏输入地址

http://spark2.x:9200/_analyze?analyzer=ik_max_word&pretty=true&text=我是程序

输出的结果为:

{
    "tokens":[
        {
            "token":"我",
            "start_offset":0,
            "end_offset":1,
            "type":"CN_CHAR",
            "position":0
        },
        {
            "token":"是",
            "start_offset":1,
            "end_offset":2,
            "type":"CN_CHAR",
            "position":1
        },
        {
            "token":"程序员",
            "start_offset":2,
            "end_offset":5,
            "type":"CN_WORD",
            "position":2
        },
        {
            "token":"程序",
            "start_offset":2,
            "end_offset":4,
            "type":"CN_WORD",
            "position":3
        },
        {
            "token":"员",
            "start_offset":4,
            "end_offset":5,
            "type":"CN_CHAR",
            "position":4
        }
    ]
}

三、搜索微服务开发

1、创建模块tensquare_search

(1)创建模块tensquare_search,并pom.xml引入依赖

tensquare_parent2020tensquare_searchpom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>tensquare_parent2020</artifactId>
        <groupId>org.study</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>tensquare_search</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
        </dependency>

        <dependency>
            <groupId>org.study</groupId>
            <artifactId>tensquare_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

(2)application.yml

tensquare_parent2020tensquare_searchsrcmainresourcesapplication.yml

server:
  port: 9007
spring:
  application:
    name: tensquare-search
  data:
    elasticsearch:
      cluster-nodes: spark2.x:9300

(3)创建包com.tensquare.search ,包下创建启动类

tensquare_parent2020tensquare_searchsrcmainjavacomtensquaresearchSearchApplication.java

package com.tensquare.search;

import com.study.util.IdWorker;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SearchApplication {
    public static void main(String[] args) {
        SpringApplication.run(SearchApplication.class,args);
    }

    @Bean
    public IdWorker idWorker(){
        return new IdWorker(1,1);
    }
}

2、添加文章 (文章保存到索引库)

(1)创建实体类(创建com.tensquare.search.pojo包,包下建立类 )

tensquare_parent2020tensquare_searchsrcmainjavacomtensquaresearchpojoArticle.java

package com.tensquare.search.pojo;


import com.sun.javafx.beans.IDProperty;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;

import java.io.Serializable;


@Document(indexName="tensquare_article",type="article")
public class Article implements Serializable {

    @Id
    private String id;

    //是否索引,就是看该域是否能被搜索
    //是否分词,就表示搜索的时候是整体匹配还是单词匹配
    //是否存储,就是是否在页面上显示
    @Field(index=true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
    private String title;

    @Field(index=true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
    private String content;

    private String state; //审核状态

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

(2)创建数据访问接口(创建com.tensquare.search.dao包,包下建立接口)

tensquare_parent2020tensquare_searchsrcmainjavacomtensquaresearchdaoArticleDao.java
package com.tensquare.search.dao;

import com.tensquare.search.pojo.Article;

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

/**
 * 创建数据访问接口(文章数据访问层接口)文章保存到索引库
 */
public interface ArticleDao extends ElasticsearchRepository<Article,String> {
}

(3)创建业务逻辑类 (创建com.tensquare.search.service包,包下建立类 )

tensquare_parent2020tensquare_searchsrcmainjavacomtensquaresearchserviceArticleService.java

package com.tensquare.search.service;

import com.tensquare.search.dao.ArticleDao;
import com.tensquare.search.pojo.Article;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class ArticleService {

    @Autowired
    private ArticleDao articleDao;

    /**
     *  文章保存到索引库
     * @param article
     */
    public void save(Article article){
        articleDao.save(article);
    }
}

(4)创建控制器类 (创建com.tensquare.search.controller包,包下建立类 )

tensquare_parent2020tensquare_searchsrcmainjavacomtensquaresearchcontrollerArticleController.java

package com.tensquare.search.controller;

import com.study.entity.Result;
import com.study.entity.StatusCode;
import com.tensquare.search.pojo.Article;
import com.tensquare.search.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


@RestController
@RequestMapping("/article")
@CrossOrigin
public class ArticleController {
    @Autowired
    private ArticleService articleService;

   /**
     * 文章保存到索引库
     * @param article
     * @return
     */
    @RequestMapping(method= RequestMethod.POST)
    public Result save(@RequestBody Article article){
        articleService.save(article);
        return new Result(true, StatusCode.OK,"添加成功");
    }
}

(5)启动主程序SearchApplication

33ad0576f8f00bde4d8b96955a688892.png

(6)postman测试

82a9bfc72a4ec7b0015e20d043839e4d.png

b820580f52106c9ea51306be3319b443.png

3、从索引库中搜索文章

(1)controller层

tensquare_parent2020tensquare_searchsrcmainjavacomtensquaresearchcontrollerArticleController.java
  /**
     * 从索引库中搜索文章(文章搜索)
     * @param key  键值
     * @param page 页数
     * @param size 页码大小
     * @return
     */
    @RequestMapping(value="/{key}/{page}/{size}",method=RequestMethod.GET)
    public Result findByKey(@PathVariable String Key,@PathVariable int page,@PathVariable int size){
        Page<Article> pageData = articleService.findByKey(Key,page,size);
        return new Result(true,StatusCode.OK,"查询成功",new PageResult<Article>(pageData.getTotalElements(),pageData.getContent()));
    }
}

(2)service层

tensquare_parent2020tensquare_searchsrcmainjavacomtensquaresearchserviceArticleService.java

 /**
     * 从索引库中搜索文章(文章搜索)
     * @param key
     * @param page
     * @param size
     * @return
     */
    public Page<Article> findByKey(String key, int page, int size) {
        Pageable pageable = PageRequest.of(page - 1, size);
       return articleDao.findByTitleOrContentLike(key, key, pageable);
    }
}

(3)dao层

tensquare_parent2020tensquare_searchsrcmainjavacomtensquaresearchdaoArticleDao.java

package com.tensquare.search.dao;
import com.tensquare.search.pojo.Article;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

/**
 * 创建数据访问接口(文章数据访问层接口)
 */
public interface ArticleDao extends ElasticsearchRepository<Article,String> {

    /**
     *从索引库中搜索文章(文章搜索)
     * @param title    标题
     * @param content 文章正文
     * @param pageable
     * @return
     */
    public Page<Article> findByTitleOrContentLike(String title, String content, Pageable pageable);
}

(4)启动主程序SearchApplication

a10114ced0c8f5e79b28b020b3846b41.png

(5)postman测试

7411d793ede2ebe65994b129eb4b8e3b.png

4、 logstash的安装

软件下载:链接:https://pan.baidu.com/s/1cNp6QC13dAtwyN8AhNhPZg

提取码:nbma

Logstash

(1)什么是Logstash

Logstash是一款轻量级的日志搜集处理框架,可以方便的把分散的、多样化的日志搜集起来,并进行自定义的处理,然后传输到指定的位置,比如某个服务器或者文件。

(2)Logstash安装与测试

  • 解压文件

6cdab7c4114878f844d8d8a86bf09801.png
  • 解压,进入bin目录,执行如下命令:
logstash  -e 'input { stdin { } } output { stdout {} }' 

如图所示:

a86f2405cce1cb04f71ee287bd16ede0.png

f94b5918f69de9d4d54caaa7b30248ca.png
Logstash测通

参数说明:

stdin,表示输入流,指从键盘输入
stdout,表示输出流,指从显示器输出
命令行参数:
-e 执行
--config 或 -f 配置文件,后跟参数类型可以是一个字符串的配置或全路径文件名或全路径
路径(如:/etc/logstash.d/,logstash会自动读取/etc/logstash.d/目录下所有*.conf 的文
本文件,然后在自己内存里拼接成一个完整的大配置文件再去执行)

5、logstash的同步数据库

准备工作(同步文件):

链接:https://pan.baidu.com/s/19E3_8O3h6uSVg0ZI_IKFJg

提取码:bwg8

下载完毕之后,拷贝到logstash-5.6.8文件目录下,如图所示:

59049b9e006b4edb24e3e5b905c1f5d6.png

点击进去:

58fea6ba5966494b3adaba20390691e3.png

9d47eb71933c9a52621d1d385a05e08f.png

为了直观查看,我们先在mysql数据库添加一些参数:

61e17d69bf378f33f909773c8bbd2805.png
tb_article表

启动Logstash

logstash -f ../mysqlect/mysql.conf

如图所示:

69c1c091a9d60aa4b335a75f4138fb43.png

5f772e75ab45cea440c19abee842f29b.png

之后,在es的索引查看

f725976b86521c16dd299c5fd6a005c6.png

73ab0c7cf93ff38a716dd93105033368.png

跟我们刚才添加的数据库一致,时间段也是10月3号,说明同步操作成功了

若我们把mysql的数据库删除后,Logstash重新打印一次(只会打印mysql数据库还在的数据),如图所示

a935df5c2c979e3b30b195b6633d6d91.png

索引的数据是不会被删除的,如图所示:

8d96406ac6d3b8e836dc89da0262a1f6.png

面试问题总结

1、你在项目中如何开发搜索模块?

elasticsearch Spring DataElasticsearch

2、你如何实现数据库与索引库的同步?

采用Logstash

3、你如何实现索引库的分词 ?

IK 两种算法 最少切分 最细切分

4、Solr Elasticsearch性能区分

https://www.cnblogs.com/chowmin/articles/4629220.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值