ES搜索引擎

   由于最近公司的的线上商城发现了对于商品搜索的问题,之前用的是mysql数据库进行实现的。当用户输入关键字的时候,就会在数据库里对商品名称进行模糊查询。这样查询的弊端有几个

   1:当数据量大的时候,用like效率往往不高

    2:满足不了日常的搜索需求,比如搜索儿童口罩,用like,是查询不到儿童一次性口罩的。这并不是我们想要的。

    所以就决定把搜索引擎独立出来。

      因为ES无论是从效率,还是结果上都符合我们的预期。并且ES的更新比较活跃。

     一、关于ES的安装

       ES的安装网上有很多资料,不过自己要注意自己安装的ES版本。大版本之间的区别还是挺大的。

        我这里安装的是ES7.6.2,我的资源里面有,相关的插件也在里面。可以打包下载。

         ES安装

        1、将包放进服务器(我这是linx),然后解压缩 :

tar -zxvf elasticsearch-7.6.2-linux-x86_64.tar.gz

         解压完成后会有一个

         elasticsearch-7.6.2的文件夹

        2、进入文件夹修改config文件下的elasticsearch.yml文件 命令vi elasticsearch.yml

         编辑的内容如下

         cluster.name: xl#集群名称

         node.name: xl-node-1 #节点名称

         #数据和日志的存储目录

         path.data: /usr/local/bin/es-groot/elasticsearch-7.6.2/data

         path.logs: /usr/local/bin/es-groot/elasticsearch-7.6.2/logs

         #设置绑定的ip,设置为0.0.0.0以后就可以让任何计算机节点访问到了

         network.host: 0.0.0.0

         http.port: 9200 #端口

        #设置在集群中的所有节点名称,这个节点名称就是之前所修改的,当然你也可以采用默认的也行,目前是单机,放入一个节点即可

        cluster.initial_master_nodes: ["xl-node-1"]

       #跨域用(等下安装HEAD的时候会牵扯到跨域问题)

        http.cors.enabled: true

        http.cors.allow-origin: "*"

      到此基本配置结束。

      3、elasticsearch是不允许使用root账户启动的。

          adduser username

          passwd grootes

       4、把整个解压目录的权限给这个用户

          chown username /usr/local/elasticsearch-7.6.2  -R

      5.修改elasticsearh根目录下bin目录中的elasticsearch脚本。

          export JAVA_HOME=/usr/local/elasticsearch-7.6.2/jdk/

          export PATH=$JAVA_HOME/bin:$PATH

          在开头添加这两行,这一步主要是用EL的内置jdk,因为EL所需要的JDK版本极有可能和你的JDK版本不一样,所以直接用内置JDK

        6  修改jvm.options

         将 : -XX:+UseConcMarkSweepGC

         改为:-XX:+UseG1GC

        因为内置版本会影响回收机制,需要修改配置,否则启动报错

        7、这个时候就可以到bin下面启动了

         ./elasticsearch -d(-d是后台启动)

       然后再网页进行验证输入ip:9200会出一下界面

       

       这说明我们启动成功了。

      二、安装ik分词器

      在elasticsearch-7.6.2/plugins下创建ik文件夹

      Mkdir ik

      将压缩包解压到ik文件夹下面 unzip  elasticsearch-7.6.2.zip

      重启elasticsearch 

     可以用postman进行验证是否安装成功

    

     如果和图片上一样,那么就安装成功了

       三、接下来我们安装HEAD插件。

         HEAD是EL集群管理工具,也可以当做可视化工具。

          1、将  elasticsearch-head-master.zip进行加压 unzip  elasticsearch-head-master.zip

          解压完成后进入 elasticsearch-head ,然后执行npm install (没有命令的先安装nodejs

          然后直接启动 npm run start

          访问ip:9100查看是否安装成功

        四、ES基本概念

        索引,类型,文档,字段。

       对应关系型数据可以理解为索引对应数据库,类型对应表,文档对应数据,字段对应字段。

       所以我们的第一步是建立索引。

        可以先到刚才的HEAD页面进行操作

        

       

       其中有几个参数需要填写。索引名称,分片数,副本数,索引名称就是数据库名称。分片数是把数据存储成几份,比如10条数据设置的分片数是2,则会分成两份存储,每一份存5条。副本数就是产生的副本数量。单分片超过50G可能影响性能,所以根据实际需求进行分片设置。这里我们建立一个people的索引,分片数1,副本数0

      建立完成后

       这个时候,我们的索引就建立完成了

       然后想索引中插入一个文档,这里的文档指的就是一条数据。

      

        存入一条name为刘大虎的数据,然后进行查询,people后面的"_doc是类型,也就是数据库中的表名字,由于后面的版本这个会去除,所以这个版本也只允许一个index只有一个type了。所以可以固定一个死的。这里用了_doc

        

查询条件中加入 刘,刘大虎,大虎,虎子,都可以查询出来结果,因为我们在添加这条数据的时候,ES默认对他进行了分词处理,ES自带的分词器对中文的分词是一个字一个字的,也就是在添加数据的时候,ES把刘大虎这个字段分别建立了刘,大,虎三个索引。用math匹配也会自动为你进行分词处理。你的搜索条件是虎子的时候,就会把你的搜索条件拆分成虎,子两个字和索引进行匹配。所以是可以查到的,但是这也并不是我们想要的结果。查分的颗粒度太小。一方面会占用大量的存储空间,一方面会匹配到很多完全不相关的搜索结果。这里就要用到IK分词插件了,对中文有良好的支持,并且可以扩展自定义字典。在建立索引的时候我们就要指定哪些是需要进行分词索引的,因为毕竟分词索引占用的空间比较多,一个说明内容分词出来的索引可能达上百个。

现在我们重新建立所以

{
    "settings" : {
    	 "number_of_shards" :   1, //分片数
         "number_of_replicas" : 0, //备份数
        "analysis" : {
            "analyzer" : {
                "ik" : {
                    "tokenizer" : "ik_max_word"
                }
            }
        }
    },
    "mappings" : {
            "properties" : {
                  "intro" :
                  {    "type": "text", //字段类型
                    "analyzer": "ik_max_word",  //分词器
                    "search_analyzer": "ik_max_word" //搜索时用的分词器
                  },
                "title" : {
                    "type": "text",
                    "analyzer": "ik_max_word",
                    "search_analyzer": "ik_max_word"
                },
                "name":{
                   "type":"keyword"
                }
        }
        
    }
}

我们制定了intro字段为IK分词,查询IK分词。title字段也一样,name指定为不分词。我们分别插入数据测试 ,最后再详细说其中的原因和详细配置项

       

这个时候进行查询发现

     

   输入儿童口罩可以查询到,那会不会还是索引的颗粒度最小化了呢,我们再输入一个儿子,发现结果就查不到了。证明这次的索引建立规则和之前的规则不一样的,这次是数据在保存的时候,IK按照中文词汇进行了字段分词,将儿童一次性口罩分成了儿童,一次性,一次,口罩存入了索引之中,在查询的时候也会将查询条件进行中文词汇分词,输入儿童口罩,会自动分成儿童,口罩,两个词,然后去匹配索引,任一匹配到,将返回结果。

      到这里是不是感觉只要在前期进行好索引的建立。字段的初始化配置。后期只要使用就行了。很方便。

      那我们就来看一看建立一个索引的时候需要的参数

    

{
    "settings" : {
    	 "number_of_shards" :   1, //分片数
         "number_of_replicas" : 0, //备份数
        "analysis" : {
            "analyzer" : {
                "ik" : {
                    "tokenizer" : "ik_max_word"
                }
            }
        }
    },
    "mappings" : {
            "properties" : {
                  "intro" :
                  {    "type": "text", //字段类型
                    "analyzer": "ik_max_word",  //分词器
                    "search_analyzer": "ik_max_word" //搜索时用的分词器
                  },
                "title" : {
                    "type": "text",
                    "analyzer": "ik_max_word",
                    "search_analyzer": "ik_max_word"
                },
                "name":{
                   "type":"keyword"
                }
        }
        
    }
}

   ik分词经常用到的有ik_smart和ik_max_word,ik_smart分出来的词会尽量避免重复,而有价值,但是查全率低,ik_max_word会进行尽可能多的分词,但是查准率低。

    为了使得同时提高查全率和查准率,可以在建立索引的时候用ik_max_word分词,在查询的时候用ik_smart分词。这样可能造成的结果就是ik_smart分出来的词如果在ik_max_word建立的索引中不存在(比如一些网红词汇,ik_max_word需要更新词库才能分出来),那么将搜索不到。比较暴力的解决办法就是将查询和搜索都用ik_max_word。根绝业务功能选择

    

 

 

 

 

 

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值