zoukankan      html  css  js  c++  java
  • 1. 搜索引擎基础1

    elasticsearch

    简介

    	Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。
    无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。
    	Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,
    但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单
    
    elasticsearch除了Lucene和全文搜索,我们还可以描述它:
        1.分布式的实时文件存储,每个字段都被索引并可被搜索
        2.分布式的实时分析搜索引擎
        3.可以扩展到上百台服务器,处理PB级结构化或非结构化数据。
    

    1.必须提前安装Java环境

    [root@cs ~]# yum install java-1.8.0-openjdk.x86_64 -y
    [root@cs ~]# java -version
    

    2.安装

    官网地址: https://www.elastic.co/cn/

    elasticsearch,kibana,filebeat 必须保持相关软件版本一致

    # 安装环境
    centos7.9 + elasticsearch-6.8.15
    
    # 下载
    wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.8.15.rpm
    
    # 安装,使用yum安装和rpm命令安装都行
    # yum install elasticsearch-6.8.15.rpm -y
    rpm -ivh elasticsearch-6.8.15.rpm
    
    # 运行
    systemctl enable elasticsearch.service    # 加入开机启动
    # 运行/停止运行/重启/状态
    systemctl start/stop/restart/status elasticsearch.service 
    systemctl is-active elasticsearch.service  # 确认es服务是否还活着
    
    # 检查是否启动成功
    curl localhost:9200
    

    3.相关文件查看

    # rpm -ql elasticsearch
    [root@cs tmp]# rpm -qc elasticsearch
    /etc/elasticsearch/elasticsearch.yml             # es配置文件
    /etc/elasticsearch/jvm.options                   # java虚拟机的配置文件
    /etc/elasticsearch/log4j2.properties             # es的日志使用的log4j的框架,所以有log4j的配置
    /etc/elasticsearch/role_mapping.yml
    /etc/elasticsearch/roles.yml
    /etc/elasticsearch/users
    /etc/elasticsearch/users_roles
    /etc/init.d/elasticsearch                        # init.d启动脚本
    /etc/sysconfig/elasticsearch                     # 一些环境变量,一般不用更改
    /usr/lib/sysctl.d/elasticsearch.conf             # 环境变量相关            
    /usr/lib/systemd/system/elasticsearch.service    # systemd启动脚本
    
    /var/log/elasticsearch/elasticsearch.log		# es的日志文件
    /usr/share/elasticsearch/						# es的安装目录
    /usr/share/elasticsearch/bin/elasticsearch-plugin  # es用来下载插件的
    /usr/share/elasticsearch/plugins/				# es的插件目录
    

    4.修改配置文件

    # 手动创建个es的数据目录
    [root@cs tmp]# mkdir -p /data/elasticsearch_data
    [root@cs tmp]# chown -R elasticsearch:elasticsearch /data/elasticsearch_data/
    [root@cs tmp]# vim /etc/elasticsearch/elasticsearch.yml
    
    # 更改后的配置文件内容如下
    [root@cs tmp]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml 
    node.name: node-1
    # 保存数据和日志的目录
    path.data: /data/elasticsearch_data
    path.logs: /var/log/elasticsearch
    bootstrap.memory_lock: true # 锁定内存
    # 监听本机的ip,多个ip逗号间隔
    network.host: 192.168.189.128,127.0.0.1 
    
    # 完事重启服务
    [root@cs tmp]# systemctl restart elasticsearch
    # 然后观察日志,你会发现,有报错:
    [root@cs tmp]# tail -f /var/log/elasticsearch/elasticsearch.log 
    '''
    [1]: memory locking requested for elasticsearch process but memory is not locked
    '''
    
    # 报错意思是锁定内存失败,参考官网的解决办法:
    [root@cs tmp]# sudo systemctl edit elasticsearch
    
    # 添加下面两行代码
    [Service]
    LimitMEMLOCK=infinity
    
    [root@cs tmp]# sudo systemctl daemon-reload
    [root@cs tmp]# systemctl restart elasticsearch
    

    5.安装es-head 插件-- 小型可视化工具

    chrome的应用商店打不开的话,去这个地址

    谷歌浏览器添加扩展插件

    引擎可视化工具 - kibana安装

    1.安装

    # 在安装kibana之前,请确保java环境和elasticsearch都已配置并启动成功。
    # 安装环境:
    	elasticsearch-6.8.15 + kibana-6.8.15 + centos7.9
    
    # 下载安装
    [root@cs tmp]# wget https://artifacts.elastic.co/downloads/kibana/kibana-6.8.15-x86_64.rpm
    [root@cs tmp]# rpm -ivh kibana-6.8.15-x86_64.rpm
    
    # 启动/状态/重启/停止/加入开机自启/取消开机自启
    [root@cs tmp]# systemctl start/status/restart/stop/enable/disable kibana
    

    2.相关目录

    /etc/kibana/kibana.yml        # kibana配置文件
    /usr/share/kibana             # kibana安装目录
    

    3.修改配置文件

    [root@cs tmp]# vim /etc/kibana/kibana.yml 
    [root@cs tmp]# grep "^[a-Z]" /etc/kibana/kibana.yml 
    # 监听的ip和端口
    server.port: 5601
    server.host: "192.168.189.128"  
    server.name: "10.0.0.200-kibana"                      # kibana的服务名
    elasticsearch.hosts: ["http://192.168.189.128:9200"]       # 访问指定es的hosts
    
    # 重启
    [root@cs tmp]# systemctl restart kibana
    

    使用kibana操作es

    1.简单操作 -- 增删改查

    # 创建一篇文档 -- 索引/映射类型/文档id
    # 首先检查索引是否存在,不存在先创建索引,再创建文档
    PUT zhifou/doc/1
    {
      "name":"顾老二",
      "age":30,
      "from": "gu",
      "desc": "皮肤黑、武器长、性格直",
      "tags": ["黑", "长", "直"]
    }
    
    

    # 删除指定文档
    DELETE zhifou/doc/4
    
    # 删除指定索引
    DELETE /zhifou
    
    

     # doc里指定要修改的字段和内容
    POST zhifou/doc/1/_update
    {
      "doc": { # doc里指定
        "desc": "皮肤很黄",
        "tags": ["很黄","很长", "很直"]
      }
    }
    
    

    # 1.查询所有索引
    GET _cat/indices?v
    
    # 2.查询指定索引内容
    GET zhifou/_search
    GET zhifou/doc/_search # 指定类型
    
    # 3.查询指定文档内容
    GET zhifou/doc/1
    
    

    2.复杂查询

    1.准备数据

    PUT zhifou/doc/1
    {
      "name":"顾老二",
      "age":30,
      "from": "gu",
      "desc": "皮肤黑、武器长、性格直",
      "tags": ["黑", "长", "直"]
    }
    
    PUT zhifou/doc/2
    {
      "name":"大娘子",
      "age":18,
      "from":"sheng",
      "desc":"肤白貌美,娇憨可爱",
      "tags":["白", "富","美"]
    }
    
    PUT zhifou/doc/3
    {
      "name":"龙套偏房",
      "age":22,
      "from":"gu",
      "desc":"mmp,没怎么看,不知道怎么形容",
      "tags":["造数据", "真","难"]
    }
    
    
    PUT zhifou/doc/4
    {
      "name":"石头",
      "age":29,
      "from":"gu",
      "desc":"粗中有细,狐假虎威",
      "tags":["粗", "大","猛"]
    }
    
    PUT zhifou/doc/5
    {
      "name":"魏行首",
      "age":25,
      "from":"广云台",
      "desc":"仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!",
      "tags":["闭月","羞花"]
    }
    
    

    2.两种查询方式

    字符串查询 -- 不推荐使用

    # q后边是查询条件
    GET zhifou/doc/_search?q=age:18
    GET zhifou/_search?q=age:18
    
    

    结构化查询 - match查询

    # 1.match:返回所有匹配的分词。
        # 查询条件是一步步构建出来的,将查询条件添加到match中即可,对查询条件进行分词
        GET zhifou/doc/_search
        {
          "query": {
            "match": {
              "from": "gu"
            }
          }
        }
        
    # 2.match_all:查询全部。
    # match_all的值为空,表示没有查询条件,那就是查询全部
        GET zhifou/doc/_search
        {
          "query": {
            "match_all": {}
          }
        }
        
    # 3.match系列之match_phrase(短语查询)
    # 使用match的话,中文会被分成一个一个的字,构不成短语查询,没有意义
        GET zhifou/doc/_search
        {
          "query": {
            "match_phrase": {
            # 字段 : 想要查询的短语
              "desc": "仿佛"
            }
          }
        }
        
    # 4.match系列之match_phrase_prefix(最左前缀查询)
    # 当你记不住想要查询的完整单词,可以写最前边的几个字母进行查询
        GET zhifou/_search
        {
          "query": {
            "match_phrase_prefix": {
            # 查询来自前缀为sh的文档
              "from": "sh"
            }
          }
        }
        
    # 5.match系列之multi_match(多字段查询)
    # 适用多个字段查询一样的条件
        GET t3/doc/_search
        {
          "query": {
            "multi_match": {
              "query": "beautiful", # 查询条件
              "fields": ["title", "desc"] # 查询字段
            }
          }
        }
    # 5.1 multi_match甚至可以当做match_phrase和match_phrase_prefix使用,只需要指定type类型即可
    	# 最左前缀查询
        GET t3/doc/_search
        {
          "query": {
            "multi_match": {
              "query": "gi",
              "fields": ["title"],
              "type": "phrase_prefix"
            }
          }
        }
        # 短语查询
        GET t3/doc/_search
        {
          "query": {
            "multi_match": {
              "query": "girl",
              "fields": ["title"],
              "type": "phrase"
            }
          }
        }
    
    

    3.排序查询 -- sort

    # 升序:asc -- 降序:desc
    # 比如我们查询顾府都有哪些人,并根据age字段按照升序降序排列
    GET zhifou/doc/_search
    {
      "query": {
        "match": {
          "from": "gu"
        }
      },
      "sort": [
        {# 排序字段
          "age": {
            "order": "asc" # 升序
          }
        }
      ]
    }
    
    

    4.分页查询 - from/size

    # from:从哪开始查 -- size:查几个
        GET zhifou/doc/_search
        {
          "from": 0,
          "size": 2
        }
        
    
    

    5.布尔查询 -- bool

    must:与关系,相当于关系型数据库中的and。
    should:或关系,相当于关系型数据库中的or。
    must_not:非关系,相当于关系型数据库中的not。
    filter:过滤条件。
        -range:条件筛选范围。
            gt:大于,相当于关系型数据库中的>。
            gte:大于等于,相当于关系型数据库中的>=。
            lt:小于,相当于关系型数据库中的<。
            lte:小于等于,相当于关系型数据库中的<=。
    
    

    基本操作

    # 1.must 与 -- 查询from=gu和age=30的文档
        GET zhifou/_search
        {
          "query": {
            "bool": {
            # 查询关系类型,是个列表里放查询条件
              "must": [
                {
                  "match": {
                    "from": "gu"
                  }
                },
                {
                  "match": {
                    "age": "30"
                  }
                }
              ]
            }
          }
        }
        
    # 2.should 或 -- 查询只要是from为gu或者tags为闭月的数据
        GET zhifou/doc/_search
        {
          "query": {
            "bool": {
              "should": [
                {
                  "match": {
                    "from": "gu"
                  }
                },
                {
                  "match": {
                    "tags": "闭月"
                  }
                }
              ]
            }
          }
        }
        
    # 3. must_not 非 -- 想要查询from既不是gu并且tags也不是可爱,还有age不是18的数据
        GET zhifou/doc/_search
        {
          "query": {
            "bool": {
              "must_not": [
                {
                  "match": {
                    "from": "gu"
                  }
                },
                {
                  "match": {
                    "tags": "可爱"
                  }
                },
                {
                  "match": {
                    "age": 18
                  }
                }
              ]
            }
          }
        }
        
    # 4. filter 过滤查询 -- 要查询from为gu,age大于25的数据
    # filter最好与must一起使用,因为查询过程中,优先经过filter过滤,如果是should的话,结果会不准确
        GET zhifou/doc/_search
        {
          "query": {
            "bool": {
              "must": [
                {"match": {
                  "from": "gu"
                }}
              ], 
              "filter": {
                "range": {
                # 过滤字段
                  "age": {
                  # 过滤范围
                    "gt": 25
                  }
                }
              }
            }
          }
        }
    
    

    6.结果过滤:_source

    # 在所有的结果中,我只需要查看name和age两个属性,其他的不要怎么办
        GET zhifou/_search
        {
          "query": {
            "match": {
              "from": "gu"
            }
          }, 
          # 把我们想要看到的数据放到列表中
          "_source": ["name","age"]
        }
    
    

    7.高亮查询 :highlight -- 查询条件在结果中高亮显示

    # 1.默认高亮显示
        GET zhifou/_search
        {
          "query": {
            "match_phrase": {
              "name": "石头"
            }
          }, 
          "highlight": {
            "fields": {
            # 需要高亮显示查询条件的字段
              "name": {},
              "tags": {}
            }
          }
        }
    
    # 2.自定义样式高亮显示
        GET zhifou/chengyuan/_search
        {
          "query": {
            "match": {
              "from": "gu"
            }
          },
          "highlight": {
            # 开始标签 -- 可以写样式
            "pre_tags": "<b style='color:red'>",
            # 结束标签
            "post_tags": "</b>",
            "fields": {
              "from": {}
            }
          }
        }
    
    

    8.聚合函数 - 分组查询: aggs

    注意:聚合函数的使用,一定是先查出结果,然后对结果使用聚合函数做处理
    avg:求平均
    max:最大值
    min:最小值
    sum:求和
    分组查询
    
    

    基本操作:

    # 1.avg -- 查询from是gu的人的平均年龄
        GET zhifou/doc/_search
        {
          "query": {
            "match": {
              "from": "gu"
            }
          },
          "aggs": {
          	# 自定义函数别名
            "pingjun": {
            # 聚合函数类型 -- 可以替换成其他类型
              "avg": {
              # 字段
                "field": "age"
              }
            }
          },
          # 不想看查询数据,只想看聚合函数值
          "size": 0
        }
    
    # 2.分组查询 
    # 想要查询所有人的年龄段,并且按照15~20,20~25,25~30分组,并且算出每组的平均年龄
        GET zhifou/doc/_search
        {
          "size": 0, 
          "query": {
            "match_all": {}
          },
          # 分组
          "aggs": {
           # 分组别名
            "age_group": {
            # 分组
              "range": {
              # 想要分组字段
                "field": "age",
                # 分组范围列表
                "ranges": [
                  {
                    "from": 15,
                    "to": 20
                  },
                  {
                    "from": 20,
                    "to": 25
                  },
                  {
                    "from": 25,
                    "to": 30
                  }
                ]
              },
              # 平均值
              "aggs": {
                "my_avg": {
                  "avg": {
                    "field": "age"
                  }
                }
              }
            }
          }
        }
    
    

    3.自定义索引结构: mappings 映射

    1.mappings三种映射,具体由dynamic属性控制

    • 动态映射: dynamic:true -- 默认模式
    • 静态映射: dynamic:false
    • 严格模式: dynamic:strict
    动态映射
    # 定义了两个字段类型,当添加新字段sex时,也可以使用新字段进行数据查询
    # 因为elasticsearch已经为新增的sex建立了映射关系
    PUT m1
    {
      "mappings": {
        "doc":{
          "dynamic":true,   # 默认动态可不写
          "properties": {
            "name": {
              "type": "text"
            },
            "age": {
              "type": "long"
            }
          }
        }
      }
    }
    
    
    静态映射
    # 定义了两个字段类型,可以添加新字段sex时,但是使用新字段查询不到数据
    # 因为elasticsearch并没有为新增的sex建立映射关系
    PUT m2
    {
      "mappings": {
        "doc":{
          "dynamic":false,   
          "properties": {
            "name": {
              "type": "text"
            },
            "age": {
              "type": "long"
            }
          }
        }
      }
    }
    
    
    严格模式
    # 定义了两个字段类型,添加新字段,报错,只能添加已经定义的字段数据
    PUT m3
    {
      "mappings": {
        "doc": {
          "dynamic": "strict", 
          "properties": {
            "name": {
              "type": "text"
            },
            "age": {
              "type": "long"
            }
          }
        }
      }
    }
    
    

    小结:

    • 动态映射(dynamic:true):动态添加新的字段(或缺省)。
    • 静态映射(dynamic:false):忽略新的字段。在原有的映射基础上,当有新的字段时,不会主动的添加新的映射关系,只作为查询结果出现。
    • 严格模式(dynamic: strict):如果遇到新的字段,就抛出异常。

    2.index -- 定义是否字段创建索引

    首先来创建一个mappings

    PUT m4
    {
      "mappings": {
        "doc": {
          "dynamic": false,
          "properties": {
            "name": {
              "type": "text",
              "index": true
            },
            "age": {
              "type": "long",
              "index": false
            }
          }
        }
      }
    }
    
    

    3.settings 设置主 - 复制分片

    在创建一个索引的时候,我们可以在settings中指定分片信息

    PUT s1
    {
      "mappings": {
        "doc": {
          "properties": {
            "name": {
              "type": "text"
            }
          }
        }
      }, 
      "settings": {
        "number_of_replicas": 1,
        "number_of_shards": 5
      }
    }
    
    # number_of_shards是主分片数量(每个索引默认5个主分片)
    # number_of_replicas是复制分片,默认一个主分片搭配一个复制分片
    
    
  • 相关阅读:
    软件工程课堂二
    软件工程第二周总结
    软件工程第一周开课博客
    软件工程课堂一
    开学第一次考试感想
    以Function构造函数方式声明函数
    document.scrollingElement
    标识符
    变量声明语句的提升
    用that代替this
  • 原文地址:https://www.cnblogs.com/jia-shu/p/14805459.html
Copyright © 2011-2022 走看看