当前位置 博文首页 > wang785994599的博客:1.elasticsearch概念和基本用法

    wang785994599的博客:1.elasticsearch概念和基本用法

    作者:[db:作者] 时间:2021-09-06 19:00

    全文搜索属于最常见的需求,开源的?Elasticsearch?(以下简称 Elastic)是目前全文搜索引擎的首选。

    它可以快速地储存、搜索和分析海量数据。维基百科、Stack Overflow、Github 都采用它。

    Elastic 的底层是开源库?Lucene。但是,你没法直接用 Lucene,必须自己写代码去调用它的接口。Elastic 是 Lucene 的封装,提供了 REST API 的操作接口,开箱即用。

    一、安装

    安装 Elasticsearch 之前,你需要先安装一个较新的版本的 Java,最好的选择是,你可以从?www.java.com获得官方提供的最新版本的 Java。

    然后下载最新版本的elastic:https://www.elastic.co/downloads/elasticsearch,或者找到需要的版本下载。

    解压

    cd elasticsearch-<version>
    ./bin/elasticsearch 
    可选参数 -d 守护进程后台运行
    

    Elastic 只允许本机访问,如果需要远程访问,可以修改 Elastic 安装目录的config/elasticsearch.yml文件,去掉network.host的注释,将它的值改成0.0.0.0,然后重新启动 Elastic。

    线上服务要设置指具体ip。

    ?

    二、基本概念

    2.1node与cluster

    Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例。

    单个 Elastic 实例称为一个节点(node)。一组节点构成一个集群(cluster)。

    文档元数据

    一个文档不仅仅包含它的数据?,也包含?元数据?——?有关?文档的信息。?三个必须的元数据元素如下:

    _index

    文档在哪存放

    _type

    文档表示的对象类别

    _id

    文档唯一标识

    _index

    一个?索引?应该是因共同的特性被分组到一起的文档集合。 例如,你可能存储所有的产品在索引?products中,而存储所有销售的交易到索引?sales?中。 虽然也允许存储不相关的数据到一个索引中,但这通常看作是一个反模式的做法。

    ?

    实际上,在 Elasticsearch 中,我们的数据是被存储和索引在?分片?中,而一个索引仅仅是逻辑上的命名空间, 这个命名空间由一个或者多个分片组合在一起。?然而,这是一个内部细节,我们的应用程序根本不应该关心分片,对于应用程序而言,只需知道文档位于一个?索引内。 Elasticsearch 会处理所有的细节。

    我们将在?索引管理?介绍如何自行创建和管理索引,但现在我们将让 Elasticsearch 帮我们创建索引。 所有需要我们做的就是选择一个索引名,这个名字必须小写,不能以下划线开头,不能包含逗号。我们用?website?作为索引名举例。

    _type

    数据可能在索引中只是松散的组合在一起,但是通常明确定义一些数据中的子分区是很有用的。 例如,所有的产品都放在一个索引中,但是你有许多不同的产品类别,比如 "electronics" 、 "kitchen" 和 "lawn-care"。

    这些文档共享一种相同的(或非常相似)的模式:他们有一个标题、描述、产品代码和价格。他们只是正好属于“产品”下的一些子类。

    Elasticsearch 公开了一个称为?types?(类型)的特性,它允许您在索引中对数据进行逻辑分区。不同 types 的文档可能有不同的字段,但最好能够非常相似。 我们将在?类型和映射?中更多的讨论关于 types 的一些应用和限制。

    一个?_type?命名可以是大写或者小写,但是不能以下划线或者句号开头,不应该包含逗号,?并且长度限制为256个字符. 我们使用?blog?作为类型名举例。

    _id

    ID?是一个字符串,?当它和?_index?以及?_type?组合就可以唯一确定 Elasticsearch 中的一个文档。 当你创建一个新的文档,要么提供自己的?_id?,要么让 Elasticsearch 帮你生成。

    ?

    三、Index的操作

    新建 Index,可以直接向 Elastic 服务器发出 PUT 请求。新建一个名为goods 的index

    $ curl -X PUT 'localhost:9200/goods'

    服务器返回如下结果,代表新建成功

    {
      "acknowledged":true,
      "shards_acknowledged":true
    }

    删除索引,发送delete请求

    curl -X DELETE 'localhost:9200/goods'

    四、中文分词插件

    在https://github.com/medcl/elasticsearch-analysis-ik/releases找到对应版本的插件,复制zip路径

    在elasticsearch安装目录中plugins目录下运行

    elasticsearch-plugin install url

    重启elastcisearch,新建一个index,指定需要分词的字段,这一步根据数据结构而异,下面的命令只针对本文。基本上,凡是需要搜索的中文字段,都要单独设置一下。

    $ curl -X PUT 'localhost:9200/accounts' -d '
    {
      "mappings": {
        "person": {
          "properties": {
            "user": {
              "type": "text",
              "analyzer": "ik_max_word",
              "search_analyzer": "ik_max_word"
            },
            "title": {
              "type": "text",
              "analyzer": "ik_max_word",
              "search_analyzer": "ik_max_word"
            },
            "desc": {
              "type": "text",
              "analyzer": "ik_max_word",
              "search_analyzer": "ik_max_word"
            }
          }
        }
      }
    }'

    上面代码中,首先新建一个名称为accounts的 Index,里面有一个名称为person的 Type。person有三个字段。

    这三个字段都是中文,而且类型都是文本(text),所以需要指定中文分词器,不能使用默认的英文分词器。

    Elastic 的分词器称为?analyzer。我们对每个字段指定分词器。

    上面代码中,analyzer是字段文本的分词器,search_analyzer是搜索词的分词器。ik_max_word分词器是插件ik提供的,可以对文本进行最大数量的分词。

    五、数据操作

    5.1新增记录

    向指定的 /Index/Type 发送 PUT 请求,就可以在 Index 里面新增一条记录。比如,向/accounts/person发送请求,就可以新增一条人员记录。

    $ curl -X PUT 'localhost:9200/accounts/person/1' -d '
    {
      "user": "张三",
      "title": "工程师",
      "desc": "数据库管理"
    }' 

    服务器返回的 JSON 对象,会给出 Index、Type、Id、Version 等信息。

    {
      "_index":"accounts",
      "_type":"person",
      "_id":"1",
      "_version":1,
      "result":"created",
      "_shards":{"total":2,"successful":1,"failed":0},
      "created":true
    }

    如果你仔细看,会发现请求路径是/accounts/person/1,最后的1是该条记录的 Id。它不一定是数字,任意字符串(比如abc)都可以。

    新增记录的时候,也可以不指定 Id,这时要改成 POST 请求。会用一个x系统生成的字符串作为id。

    $ curl -X POST 'localhost:9200/accounts/person' -d '
    {
      "user": "李四",
      "title": "工程师",
      "desc": "系统管理"
    }'

    5.2查看记录

    /Index/Type/Id发出 GET 请求,就可以查看这条记录。

    $ curl 'localhost:9200/accounts/person/1?pretty=true'

    上面代码请求查看/accounts/person/1这条记录,URL 的参数pretty=true表示以易读的格式返回。

    返回的数据中,found字段表示查询成功,_source字段返回原始记录。

    5.3删除记录

    发送delete请求

    $ curl -X DELETE 'localhost:9200/accounts/person/1'

    5.4更新记录

    更新记录就是使用 PUT 请求,重新发送一次数据。参考新建。

    六、数据查询

    6.1查询所有记录

    使用 GET 方法,直接请求/Index/Type/_search,就会返回所有记录。

    $ curl 'localhost:9200/accounts/person/_search'

    ?返回值示例:

    	{
    	  "took":2,                   #耗时  毫秒
    	  "timed_out":false,		  #是否超时
    	  "_shards":{"total":5,"successful":5,"failed":0},
    	  "hits":{                    #
    		"total":2,				  #总数
    		"max_score":1.0,		  #最高的匹配程度
    		"hits":			  #hits查询到的记录
    			{
    				"_index":"accounts",
    				"_type":"person",
    				"_id":"AV3qGfrC6jMbsbXb6k1p",
    				"_score":1.0,     #_score表示匹配的程序,默认是按照这个字段降序排列。
    				"_source": {
    				  "user": "李四",
    				  "title": "工程师",
    				  "desc": "系统管理"
          }
    	}

    6.2全文搜索

    curl 'localhost:9200/test/mytest/_search?pretty=true'  -d '
    	{
    	  "query" : { "match" : { "name" : "华为" }},
    	  "size": 10,
    	  "from": 1
    	}'
    	上句表示:从accounts索引 person Type中查找 name中包含Apple的1条 从1开始
    	size:数量
    	from:移位 上面表示从1开始 默认从0

    数据体以json格式传递

    6.3逻辑运算

    如果有多个搜索关键字, Elastic 认为它们是or关系。

    $ curl 'localhost:9200/accounts/person/_search'  -d '
    {
      "query" : { "match" : { "desc" : "软件 系统" }}
    }'

    上面代码搜索的是软件 or 系统

    如果要执行多个关键词的and搜索,必须使用布尔查询。

    $ curl 'localhost:9200/accounts/person/_search'  -d '
    {
      "query": {
        "bool": {
          "must": [
            { "match": { "desc": "软件" } },
            { "match": { "desc": "系统" } }
          ]
        }
      }
    }'

    ?

    ?

    cs