ElasticSearch笔记(2)索引、分词、DSL、聚合

一 倒排索引

1.1 什么是倒排索引

类似一些书籍后面的Index(一般以字母排序),
倒排索引(Inverted Index)也叫反向索引,有反向索引必有正向索引。通俗地来讲,正向索引是通过key找value,反向索引则是通过value找key
在这里插入图片描述
在这里插入图片描述

1.2 核心组成

单词词典(Term Dictionary)

记录所有文档的单词,记录单词到倒排列表的关联关系

倒排列表(Posting)

记录了单词对应的文档组合,由倒排索引项组成

倒排索引项

  • 文档ID
  • 词频TF-该单次在文档中出现的次数,用于相关性评分
  • 位置(position)单词在文档中分词的位置
  • 偏移(offset)该单词的开始结束位置,实现高亮显示

例子
展示ElasticSearch这个单词的倒排列表
在这里插入图片描述

1.3 倒排索引

  • 文档(json)的每个字段每个字段,都有自己的倒排索引
  • 可以对某些字段不做索引(在mapping中设置),这样这个字段就不可以被搜索

二 Analyzer-分词器

2.1 Analysis

文本分析。把全文本转换成一系列单词(token/term,这里的单词不是狭义上的英语单词),这个过程也叫分词

通过分词器(analyzer)来实现,Elasticsearch内置了一些分词器,我们也可以使用一些别人写好的分词器插件,甚至自定义。

分词的时机

  1. 数据写入时
  2. 某些查询用法

2.2 组成

分词器时专门处理分词的组件,由三部分组成
在这里插入图片描述

Character Filters

针对原始文本处理,例如去除html

Tokenizer

按照实现的规则,切分语句为单词

Token Filter

将切分后的Term(单词)进行处理,比如小写、删除stopwords、增加同义词

2.3 内置分词器

在这里插入图片描述

2.4 analyzer API

GET /_analyze
{
  "analyzer": "standard",
  "text":"i like coding"
}


//输出
{
  "tokens" : [
    {
      "token" : "i",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "like",
      "start_offset" : 2,
      "end_offset" : 6,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "coding",
      "start_offset" : 7,
      "end_offset" : 13,
      "type" : "<ALPHANUM>",
      "position" : 2
    }
  ]
}

2.5 中文分词

GET /_analyze
{
  "analyzer": "standard",
  "text":"我喜欢旅游"
}

//输出
{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<IDEOGRAPHIC>",
      "position" : 0
    },
    {
      "token" : "喜",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "<IDEOGRAPHIC>",
      "position" : 1
    },
    {
      "token" : "欢",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "<IDEOGRAPHIC>",
      "position" : 2
    },
    {
      "token" : "旅",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "<IDEOGRAPHIC>",
      "position" : 3
    },
    {
      "token" : "游",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "<IDEOGRAPHIC>",
      "position" : 4
    }
  ]
}

默认分词器不太适合中文,没有分成我们中文中的词

ICU Analyzer

在这里插入图片描述

IK

安装步骤,基于前一篇的docker-compose

  1. 从github下载对应的ik插件(注意版本
  2. 在宿主机上创建目录,解压
/test/plugins/ik
  1. 修改docker-compose.yaml。增加目录挂载
- ./plugins:/usr/share/elasticsearch/plugins
  1. 重启docker-compose

效果

GET /_analyze
{
  "analyzer": "ik_smart",
  "text":"我喜欢旅游"
}


//效果
{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "喜欢",
      "start_offset" : 1,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "旅游",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    }
  ]
}

三 URI Search

3.1 相关性

在这里插入图片描述
在这里插入图片描述

3.2 指定索引查询

在这里插入图片描述

3.3 具体语法

因为考虑到实际中,几乎不会用URI search。所以省略…

"profile"可以查看查询是如何进行的

GET /ent_search/_search?q=county:海淀区
{
  "profile": "true"
}

四 请求体查询 & DSL

4.1 分页

GET ent_search/_search
{
  "from":0,//从0开始
  "size":10,//每页条数
  "query": {
    "match_all": {
      
    }
  }
}

获取后面页数的成本较高。特别是在分布式架构下。

4.2 排序

GET ent_search/_search
{
  "from":0,
  "size":10,
  "query": {
    "match_all": {
      
    }
  },
  "sort": [
    {
      "reg_no": {
        "order": "desc"
      }
    }
  ]
}
  1. 最好在日期型或者数字型上字段排序

4.3 _source filtering

  • 只返回匹配的字段
  • 支持通配符
GET ent_search/_search
{
  "from":0,
  "size":10,
  "query": {
    "match_all": {
      
    }
  },
  "_source": ["ent_nam*","industryco"]
}

4.4 脚本字段

GET ent_search/_search
{
  "from":0,
  "size":10,
  "query": {
    "match_all": {
      
    }
  },
  "script_fields": {
    "nameplus": {
      "script": {
        "lang": "painless",
        "source": "doc['industryco'].value"
      }
    }
  }, 
  "_source": ["ent_name","industryco"]
}GET ent_search/_search
{
  "from":0,
  "size":10,
  "query": {
    "match_all": {
      
    }
  },
  "script_fields": {
    "nameplus": {
      "script": {
        "lang": "painless",
        "source": "params['_source']['ent_name']+'测试'"
      }
    }
  }, 
  "_source": ["ent_name","industryco"]
}

了解doc['my_field'].value和params ['_ source'] ['my_field']之间的区别很重要。第一使用doc关键字将导致该字段的术语被加载到内存(缓存),这将导致更快的执行,但是更多的内存消耗。此外,doc […]符号只允许简单的有值的字段(不能从中返回一个json对象),并且只对非分析或单个术语的字段有意义。但是,使用doc仍然是从文档访问值的推荐方法,如果可能的话,因为_source必须在每次使用时被加载和解析。使用_source是非常慢的。

4.5 查询表达式match

GET ent_search/_search
{
  "from":0,
  "size":10,
  "query": {
    "match": {
        "ent_name": {
          "query": "小米",
          "operator": "and"
        }
      
    }
  },
  
  "_source": ["ent_name","industryco"]
}

operator表示分词后,这些单词是or匹配还是and匹配

4.6 短语搜索-Match Phrase

GET ent_search/_search
{
  "from":0,
  "size":10,
  "query": {
    "match_phrase": {
        "ent_name": {
          "query": "小米",
          "slop":1//可以支持近似匹配
        }
      
    }
  },
  
  "_source": ["ent_name","industryco"]
}

查询语句分词后的单词全部出现在返回记录的字段中,并且出现顺序一致

4.7 query_string

GET ent_search/_search
{
  "from":0,
  "size":10,
  "query": {
    "query_string": {
       "default_field": "ent_name",
       "query":"小米"
      
    }
  },
  
  "_source": ["ent_name","industryco"]
}

GET ent_search/_search
{
  "from":0,
  "size":10,
  "query": {
    "query_string": {
       "fields": ["ent_name","address"],
       "query":"小米"
      
    }
  }
}
  • 支持多字段查询
  • 类似match_phrase,但对顺序没要求

支持布尔操作
在这里插入图片描述
在这里插入图片描述

4.8 Simple Query String

POST users/_search
{
  "query": {
    "simple_query_string": {
      "query": "trying out i",
      "fields": ["message"],
      "default_operator": "AND"
    }
  }
}

在这里插入图片描述

4.9 更多用法

上面只记录了部分用法,更多可以参考官网。或者后续文章。

五 Mapping

Mapping类似数据库中schema的定义,作用

  1. 定义索引中的字段的名称
  2. 定义字段的数据类型,例如字符串、数字、布尔…
  3. 字段、倒排索引的相关配置(Analyzed或者Not Analyzed,Analyzer分词器)

Mapping会把Json文档映射成Lucene所需要的扁平格式

关于type

  1. 每个文档都属于一个type
  2. 一个type有一个mapping定义(一个mapping中只能有一个type
  3. 从7.0开始,不需要再mapping中指定type信息

5.1 数据类型

简单类型

  • Text/Keyword
  • Date
  • Integer/Floating
  • Boolean
  • IPV4/6

复杂类型-对象和嵌套类型

特殊类型

  • geo_point & geo_shape/percolator

5.2 Dynamic Mapping

在写入文档时,如果索引不存在,则会主动创建索引(定义了一个mapping

因为Mapping是ES主动根据文档信息推算的,所以有时候会不准确

自动识别规则
在这里插入图片描述

5.3 关于Mapping的修改

新增字段

  • 如果mapping的Dynamic设为true,一旦有新增字段写入。Mapping就会更新
  • Dynamic设为false,mapping不会更新。新增字段无法被索引,但会出现在_source中
  • Dynamic设为strict,文档会写入失败

对已有字段

一旦该字段已经有数据写入,就不允许修改

如果希望改变字段类型,则必须Reindex API,重建索引

原因

  • 如果修改字段的数据类型,会导致已被索引的属于无法被搜索
  • 如果是新增字段,则不会有影响(之前还没索引

Dynamic值

在这里插入图片描述
为false时,即新增字段会被存入es中的文档。但es不会为新增字段增加倒排索引

5.4 手动定义Mapping

建议手动定义Mapping,可以更加精准地控制

  • Index属性。控制当前字段是否被索引,默认为true。如果为false,则不能被搜索
  • Index Options 控制倒排索引地内容
    在这里插入图片描述
  • null_value.只有keyword类型支持
  • copy_to(就是将多个字段合并成一个查询字段)
    在这里插入图片描述

5.5 数组类型

ES中不提供专门的数组类型。但是任何字段,都可以包含多个相同类型的数值
在这里插入图片描述

5.6 多字段特性

在这里插入图片描述

5.7 Index template

帮助设定Mappings和Settings,并按照一定的规则,自动匹配到新创建的索引上

  • 模板只会在一个索引被新创建时,才会产生作用。修改模板不会影响已创建的索引
  • 可以设置多个索引模板,这些设置会merge在一起
  • 你可以指定order的数值,控制merging的过程

在这里插入图片描述

工作方式

在这里插入图片描述

5.8 Dynamic Template

根据ElasticSearch识别的数据类型,结合字段名称,来动态设定字段类型
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

六 聚合

6.1 什么是聚合

在这里插入图片描述

在这里插入图片描述

6.2 集合的类型

ES会对结果集进行分桶(类似数据库中的group by
在这里插入图片描述
在这里插入图片描述

Bucket

在这里插入图片描述

Metric

在这里插入图片描述

例子

在这里插入图片描述
在这里插入图片描述
如(注意!这里terms和第二个aggs是同一个对象的两个属性,这表示是同一组group和avg关系):

GET ent_search/_search
{
    "from": 0,
    "size": 0,
    "aggs": {
        "county_group": {
            "terms": {
                "field": "county",
                "size":1//控制返回几个分组(按数量从多到少),默认10
            },
            "aggs": {
                "avg_price": {
                    "avg": {
                        "field": "reg_cap"
                    }
                }
            }
        }
    }
}


//效果
"buckets" : [
        {
          "key" : "海淀区",
          "doc_count" : 6754,
          "avg_price" : {
            "value" : 6290.3363345432335
          }
        },
        {
          "key" : "朝阳区",
          "doc_count" : 5218,
          "avg_price" : {
            "value" : 5923.739484373515
          }
        },
        ...

在这里插入图片描述

GET ent_search/_search
{
    "from": 0,
    "size": 0,
    "aggs": {
        "county_group": {
            "terms": {
                "field": "county"
            },
            "aggs": {
                "avg_price": {
                    "avg": {
                        "field": "reg_cap"
                    }
                },
                "industryco_name_group":{
                  "terms": {
                    "field": "industryco_name"
                  }
                }
            }
        }
    }
}

//效果
"buckets" : [
        {//先按区县统计
          "key" : "海淀区",
          "doc_count" : 6754,
          "industryco_name_group" : {
            "doc_count_error_upper_bound" : 15,
            "sum_other_doc_count" : 826,
            "buckets" : [//里面又按行业统计
              {
                "key" : "其他科技推广服务业",
                "doc_count" : 4046
              },
              {
                "key" : "其他技术推广服务",
                "doc_count" : 648
              },

参考

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值