zoukankan      html  css  js  c++  java
  • elasticsearch

    elasticsearch背景 https://www.cnblogs.com/Neeo/p/10304892.html

    我们建立一个网站或应用程序,并要添加搜索功能,但是想要完成搜索工作的创建是非常困难的。我们希望搜索解决方案要运行速度快,我们希望能有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用JSON通过HTTP来索引数据,我们希望我们的搜索服务器始终可用,我们希望能够从一台开始并扩展到数百台,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。因此我们利用Elasticsearch来解决所有这些问题及可能出现的更多其它问题。

    什么是elasticsearch?

     一个搜素服务器,它提供了一个分布式多用户能力的全文搜索引擎,也可以说是一个数据库.基于RESTful web接口,也可以作为数据库使用。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    elasticsearch特点

    • 分布式实时文档存储,并将每一个字段都编入索引,使其可以被搜索。
    • 实时分析的分布式搜索引擎。
    • 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。

    应用场景

     可以作为一个搜素的插件应用到项目中

    elasticsearch组织架构

    elasticsearch中文档,类型,索引的关系

    ①elasticsearch是面向文档的,那么就意味着索引和搜索数据的最小单位是文档;

    • 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含key:value
    • 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的
    • 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在elasticsearch中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段。
    • 文档是无模式的,也就是说,字段对应值的类型可以是不限类型的。

    ②类型是文档的容器,就像mysql一样,表是行的容器;

    类型中对于字段的定义称为映射,比如name映射为字符串类型。

    ③索引是映射类型的容器,elasticsearch中的索引是一个非常大的文档集合。索引存储了映射类型的字段和其他设置。然后它们被存储到了各个分片上了。

    什么是节点和分片?

    一个集群包含至少一个节点,而一个节点就是一个elasticsearch进程。节点内可以有多个索引。
    默认的,如果你创建一个索引,那么这个索引将会有5个分片(primary shard,又称主分片)构成,而每个分片又有一个副本(replica shard,又称复制分片),这样,就有了10个分片。如下图

    上图是一个有3个节点的集群,可以看到主分片和对应的复制分片都不会在同一个节点内,这样有利于某个节点挂掉了,数据也不至于丢失。
    实际上,一个分片是一个Lucene索引,一个包含倒排索引的文件目录,倒排索引的结构使得elasticsearch在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的关键字。

    倒排索引

    elasticsearch使用的是一种称为倒排索引的结构,采用Lucene倒排索作为底层。elasticsearch将索引被分为多个分片,每份分片是一个Lucene的索引。所以一个elasticsearch索引是由多个Lucene索引组成的。这种结构适用于快速的全文搜索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。

    如下表,进一步理解倒排索引:

    学科(原始数据) 索引列表(倒排索引)
    id 学科 语言 id
    1 语文 语文 1,2,3
    2 语文 数学 3,4
    3 语文,数学    
    4 数学    

    MySQL,MongoDB,Elasticsearch对比

    关系型数据库和非关系型数据库比对
    MySQL MongoDB Elasticsearch
    数据库(database) 数据库 索引(indices)
    表(tables) 表(Collection) types
    行(rows)  Documents Documents
    字段(columns) Field Field

    总结:MySQL为关系型数据库,而MongoDB,Elasticsearch为非关系型数据库,由此看出两者的特点比较明显;

    elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(列)。

    物理设计 ---> elasticsearch后台是如何处理这些数据的呢?elasticsearch将每个索引划分为多个分片,每份分片又可以在集群中的不同服务器间迁移。

    注意:当然,这里需要补充的是,从elasticsearch的第一个版本开始,每个文档都存储在一个索引中,并分配多个映射类型,映射类型用于表示被索引的文档或者实体的类型,但这也带来了一些问题(详情参见Removal of mapping types),导致后来在elasticsearch6.0.0版本中一个文档只能包含一个映射类型,而在7.0.0中,映射类型则将被弃用,到了8.0.0中则将完全被删除。

    elasticsearch的语法

    1.基本语法写法

    #基本语法
    #PUT创建一文档(注意大写)t1的文档
    PUT t1/doc/1
    {
      "name":"可可"
    }
    
    #查询t1的文档索引信息
    GET t1/doc/1  
    #删除索引
    DELETE t1/doc/1
    
    PUT t1/doc/2 
    {
      "name":"盼盼",
      "age":20
    }
    
    GET t1    #返回t1所有的创建信息
    GET _cat/indices   #查询所有文档的信息
    GET t1/_settings   #查询t1的主分片和复制分片情况
    GET t1/_mapping  #查看t1的映射关系结构

    创建一些数据来操作操作

    #是不是有种来到汉朝的感觉,没事,放松点,呵呵
    PUT han/doc/1
    {
        "name":"孝景帝",
        "from":"汉朝",
        "in_time":16,
        "info":"无为而治",
        "tags":["平定七国之乱","诛晁错"],
        "female":"窦太后"  
    }
    PUT han/doc/2
    {
        "name":"孝武帝",
        "from":"汉朝",
        "in_time":54,
        "info":"以战养战",
        "tags":["罢黜百家,独尊儒术","推恩令","平定北方匈奴","丝绸之路"],
        "female":"卫子夫"  
    }
    
    PUT han/doc/3
    {
        "name":"汉高祖",
        "from":"汉朝",
        "in_time":7,
        "info":"建立汉朝",
        "tags":["鸿门宴","灭秦,楚国"],
        "female":"吕雉"  
    }
    
    PUT han/doc/4
    {
        "name":"卫青",
        "from":"孝武帝",
        "in_time":2,
        "title":"关内侯",
        "info":"初伐匈奴",
        "tags":["奇袭龙城"]
    }
    
    PUT han/doc/5
    {
        "name":"李广",
        "in_time":1,
        "from":"孝武帝",
        "title":"飞将军",
        "info":"射石搏虎",
        "tags":["平七国吴楚联军"]
    }
    
    PUT han/doc/6
    {
        "name":"霍去病",
        "from":"孝武帝",
        "in_time":3,
        "title":"骠骑校尉",
        "info":"英年早逝,封景桓侯",
        "tags":["八百铁骑,直插敌后","平定朔方,打通西域"]
    }
    
    PUT han/doc/7
    {
        "name":"李广利",
        "from":"孝武帝",
        "title":"贰师将军",
        "in_time":4,
        "info":"二征大宛",
        "tags":["征服大宛"]
    }
    创建数据

    2.结构化查询(match相关)

    """match按关键字查询"""
    #match_all查询全部
    GET han/doc/_search
    {
      "query": {
        "match_all": {}
      }
    }
    #match指定字段查询,但是这样会查出来所有name字段中跟孝武帝相关的数据,列如孝景帝. GET han/doc/_search { "query": { "match": { "name":"孝武帝" } } } #单独查询某条数据match_phrase,只会查到name是'孝武帝'的数据 GET han/doc/_search { "query": { "match_phrase": { "name": "孝武帝" } } } #最左前缀查询,match_phrase_prefix,不记得字段信息了,智能匹配 GET han/doc/_search { "query": { "match_phrase_prefix": { "name": "" } } }
    #多字段查询multi_match ,查到字段中含有"帝"的数据 GET han/doc/_search { "query": { "multi_match": { "query": "", "fields": ["name","title"] } } } #multi_match甚至可以match_phrase,match_phrase_prefix使用,只要指定type即可 GET han/doc/_search { "query": { "multi_match": { "query": "", "fields": ["name"], "type": "phrase" } } } GET han/doc/_search { "query": { "multi_match": { "query": "", "fields": ["name"], "type": "phrase_prefix" } } }
    #排序sort
    
    #降序
    GET han/doc/_search
    {
      "query": {
        "match_all": {}
      },
      "sort":[
        {
          "in_time":{
            "order":"desc"
          }
        }
        ]
    }
    
    #升序
    GET han/doc/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "in_time": {
            "order": "asc"
          }
        }
      ]
    }
    排序语法
    #过滤_source
    GET han/doc/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "in_time": {
            "order": "asc"
          }
        }
      ],
      "_source": [ "from", "in_time","name"]
    }
    过滤 _source
    #分页 from从哪开始,size:展示条数,from,size也可以为-1
    GET han/doc/_search
    {
      "query": {
        "match_all": {}
      },
      "from":2,
      "size":2,
      "_source": "in_time"
    }
    分页
    #高亮 highlight
    GET han/doc/_search
    {
      "query": {
        "match": {
          "from":"孝武帝"
        }
      },
      "highlight":{
        "pre_tags":"<b style='color:red;'>",
        "post_tags":"</b>",
        "fields":{
          "from": {}
        }
      }
    }
    搜素信息 高亮
    #bool查询:must(and)/should(or)/must_not(not)
    
    #and
    GET han/doc/_search
    {
      "query": {
        "bool": {
          "must": [
            {"match": {
              "in_time": "1"
              }
            },
            {
            "match": {
              "from": "孝武帝"
              }  
            }
          ]
        }
      }
    }
    
    #or
    GET han/doc/_search
    {
      "query": {
        "bool": {
          "should": [
            {"match": {
              "from": "汉朝"
              }
            },
            {
            "match": {
              "in_time": 54
              }  
            }
          ]
        }
      }
    }
    
    #not
    GET han/doc/_search
    {
      "query": {
        "bool": {
          "must_not": [
            {"match": {
              "from": "孝武帝"
              }
            },
            {
            "match": {
              "in_time": 54
              }  
            }
          ]
        }
      }
    }
    bool查询:must,should,must_not
    #查询filter:gte(大于等于) gt(大于)lt(小于)lte(小于等于)
    
    GET han/doc/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "from": "汉朝"
              }
            }
          ],
          "filter": {
            "range": {
              "in_time": {
                "gte": 10
              }
            }
          }
        }
      }
    }
    
    #小于
    GET han/doc/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "from": "汉朝"
              }
            }
          ],
          "filter": {
            "range": {
              "in_time": {
                "lt": 10
              }
            }
          }
        }
      }
    }
    filter查询lte,lt,gt,gte
    #聚合查询:avg,sum,max,min
    GET han/doc/_search
    {
      "query": {
        "match_all": {}
      },
      "aggs": {
        "my_a1": {
          "avg": {
            "field": "in_time"
          }
        }
      }
    }
    聚合查询 aggs
    #分组
    GET han/doc/_search
    {
      "query": {
        "match_all": {}
      },
      "aggs": {
        "my_group": {
          "range": {
            "field": "in_time",
            "ranges": [
              {
                "from": 20,
                "to": 60
              }
            ]
          }
        }
      }
    }
    
    #分组再聚合
    GET han/doc/_search
    {
      "query": {
        "match_all": {}
      },
      "aggs": {
        "my_group": {
          "range": {
            "field": "in_time",
            "ranges": [
              {
                "from": 10,
                "to": 60
              }
            ]
          },
          "aggs": {
            "my_sum": {
              "sum": {
                "field": "in_time"
              }
            }
          }
        }
      }
    }
    分组查询,分组再聚合

    3.映射

    映射用来自定义一个文档及其包含的字段如何存储和索引的过程

    例如,我们可以使用映射来定义:

    • 哪些字符串应该被视为全文字段。
    • 哪些字段包含数字、日期或者地理位置。
    • 定义日期的格式。
    • 自定义的规则,用来控制动态添加字段的的映射。
    #映射mappings写法-01 dynamic没写默认为true,可以添加字段
    PUT t3
    {
      "mappings":{
        "doc":{
          "properties":{
            "name":{
              "type":"text"
            },
            "age":{
              "type":"long"
            }
          }
        }
      }
      
    }
    
    GET t3/_mapping
    
    PUT t3/doc/1
    {
      "name":"窦颖",
      "age":17,
      "desc":"可爱"
    }
    
    GET t3/doc/_search
    {
      "query": {
        "match": {
          "age": 17
        }
      }
    }
    
    #mappings写法-02 dynamic=false 不让添加字段,但不报错
    PUT t4
    {
      "mappings":{
        "doc":{
          "dynamic":false,
          "properties":{
            "name":{
              "type":"text"
            },
            "age":{
              "type":"long"
            }
          }
        }
      }
      
    }
    
    GET t4/_mapping
    
    PUT t4/doc/1
    {
      "name":"",
      "age":19,
      "desc":"可ke爱"
    }
    
    
    #mappings写法-03 dynamic=strict 严格模式,只要添加就报错
    PUT t5
    {
      "mappings": {
        "doc":{
          "dynamic":"strict",
          "properties":{
            "name":{
              "type":"text"
            }
          }
        }
      }
    }
    
    GET t5/_mapping
    
    PUT t5/doc/1
    {
      "name":"coco"
    }
    
    #缺省/严格的时候不能添加字段
    PUT t5/doc/2
    {
      "name":"cici",
      "age":9
    }
    mappings自定义形式和dynamic的三种形态
    #index属性,类似于模糊查询配置,有两种状态,当true,我们的自定义字段可以实现模糊查询,false则会报错
    
    PUT t6
    {
      "mappings": {
        "doc":{
          "properties":{
            "title":{
              "type":"text",
              "index":true
            },
            "content":{
              "type":"text",
              "index":false
            }
          }
        }
      }
    }
    
    
    PUT t6/doc/1
    {
      "title":"es长路漫漫",
      "content":"py唯你作伴"
    }
    
    #报错
    GET t6/doc/_search
    {
      "query": {
        "match": {
          "title":"漫漫"
        }
      }
    }
    
    GET t6/doc/_search
    {
      "query": {
        "match": {
          "content":"py"
        }
      }
    }
    mappings写法02 index
    #copy_to,该属性允许我们将多个字段的值复制到组字段中,然后将组字段作为单个字段进行查询。
    #copy_to写法-01
    PUT t7
    {
      "mappings": {
        "doc":{
          "properties":{
            "title":{
              "type":"text",
              "copy_to":"full_name"
            },
            "content":{
              "type":"text",
              "copy_to":"full_name"
            },
            "full_name":{
              "type":"text"
            }
          }
        }
      }
    }
    
    PUT t7/doc/1
    {
      "title":"aa",
      "content":"bb"
    }
    
    GET t7/doc/_search
    {
      "query": {
        "match": {
          "full_name": "bb"
        }
      }
    }
    
    #copy_to写法-02
    PUT t8
    {
      "mappings": {
        "doc":{
          "properties":{
            "title":{
              "type":"text",
              "copy_to":["full_name1","full_name2"]
            },
            "content":{
              "type":"text",
              "copy_to":"full_name"
            },
            "full_name1":{
              "type":"text"
            },
            "full_name2":{
              "type":"text"
            }
          }
        }
      }
    }
    mappings写法03 copy_to
    #对象属性,mappings中嵌套结构写法,查询方式:info.addr
    PUT t9
    {
      "mappings": {
        "doc":{
          "dynamic":false,
          "properties":{
            "name":{
              "type":"text"
            },
            "age":{
              "type":"long"
            },
            "info":{
              "properties":{
                "addr":{
                  "type":"text"
                },
                "tel":{
                  "type":"text"
                }
              }
            }
          }   
      }
    }
    }
    
    
    PUT t9/doc/1
    {
      "name":"vov",
      "age":19,
      "info":{
        "addr":"earth",
        "tel":"no"
      }
    }
      
    GET t9/doc/_search
    {
      "query": {
        "match": {
          "info.addr": "earth"
        }
      }
    }
    mappings写法04 对象属性
    #settings设置,设置主,复制分片.
    #number_of_shards主分片数量,默认5,number_of_replicas复制分片,默认1个
    
    PUT w1
    {
      "mappings": {
        "doc":{
          "properties":{
            "title":{
              "type":"text"
            }
          }
        }
      },
      "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 2
        
      }
    }
    
    
    GET w1
    mappings写法05 settings

    ...待续

  • 相关阅读:
    kernel structure
    linux cmd fuser/screen
    arm 指令架构
    udev 学习
    grup 2 ubuntu
    tiny6410 3.8.1 内核kgdb调试
    make 选项
    lfs 无知
    数据归一化的两种方法:最值归一化和0均值归一化
    使用随机队列实现生成迷宫
  • 原文地址:https://www.cnblogs.com/CrazySheldon1/p/10771090.html
Copyright © 2011-2022 走看看