Elasticsearch 基本原理和概念(四)

今天和大家分析es基本原理和概念:

从上面的例子中,我们看到了很多熟悉又陌生的概念,比如索引、文档等等。这些概念 和我们平时看到的数据库里的比如索引有什么区别呢?
举个例子,现在我们要保存唐宋诗词,数据库中我们们会怎么设计?诗词表 我们可能的设计如下:
要根据朝代或者作者寻找诗,都很简单,比如“ select 诗词全文 from 诗词表 where 作者 = ‘李白’”,如果数据很多,查询速度很慢,怎么办?我们可以在对应的查询字段上建立索引加速查询。 但是如果我们现在有个需求:要求找到包含“望”字的诗词怎么办?用
select 诗词全文 from 诗词表 where 诗词全文 like % % ’”,这个意味着 要扫描库中的诗词全文字段,逐条比对,找出所有包含关键词“望”字的记录。 基本上,数据库中一般的 SQL 优化手段都是用不上的。数量少,大概性能还能接 受,如果数据量稍微大点,就完全无法接受了,更何况在互联网这种海量数据的 情况下呢?
怎么解决这个问题呢,用倒排索引。
 
倒排索引 Inverted index
比如现在有:
蜀道难(唐)李白 蜀道之难难于上青天,侧身西望长咨嗟。
静夜思(唐)李白 举头望明月,低头思故乡。
春台望(唐)李隆基 暇景属三春,高台聊四望。
鹤冲天 ( ) 柳永 黄金榜上,偶失龙头望。明代暂遗贤,如何向?未遂风云便,
争不恣狂荡。何须论得丧?才子词人,自是白衣卿相。烟花巷陌,依约丹青屏障。
幸有意中人,堪寻访。且恁偎红翠,风流事,平生畅。青春都一饷。忍把浮名,
换了浅斟低唱!
都有望字,于是我们可以这么保存
 
 
如果查哪个诗词中包含上,怎么办,上述的表格可以继续填入新的记录
 
其实,上述诗词的中每个字都可以作为关键字,然后建立关键字和文档之间 的对应关系,也就是标识关键字被哪些文档包含。
所以,倒排索引就是,将文档中包含的关键字全部提取处理,然后再将关键 字和文档之间的对应关系保存起来,最后再对关键字本身做索引排序。用户在检 索某一个关键字是,先对关键字的索引进行查找,再通过关键字与文档的对应关 系找到所在文档。 在存储在关系型数据库中的数据,需要我们事先分析将数据拆分为不同的字 段,而在 es 这类的存储中,需要应用程序根据规则自动提取关键字,并形成对 应关系。这些预先提取的关键字,在全文检索领域一般被称为 term (词项),文档 的词项提取在 es 中被称为文档分析,这是全文检索很核心的过程,必须要区分 哪些是词项,哪些不是,比如很多场景下,apple apples 是同一个东西,望和 看其实是同一个动作
 
Elasticsearch 基本概念
Elasticsearch 中比较关键的基本概念有索引、文档、映射、映射类型、文档字段概念, 为了方便理解,可以和关系数据库中的相关概念进行个比对:
Elasticsearch 索引
Elasticsearch 索引是映射类型的容器。一个 Elasticsearch 索引非常像关系型
世界的数据库,是独立的大量文档集合。 当然在底层,肯定用到了倒排索引,最基本的结构就是“keyword ”和“ Posting List”, Posting list 就是一个 int 的数组,存储了所有符合某个 term 的文档 id 。另外,这个倒排索引相比特定词项出现过的文档列表,会包含更多其它信息。 它会保存每一个词项出现过的文档总数, 在对应的文档中一个具体词项出现的 总次数,词项在文档中的顺序,每个文档的长度,所有文档的平均长度等等相关 信息。
文档 (Document)
文档是 es 中所有可搜索数据的最小单位,比如日志文件中的日志项、一部 电影的具体信息等等。 文档会被序列化 JSON 格式保存到 ElasticSearch 中, JSON 对象由字段组成, 每个字段都有对象的字段类型(字符串,数值,布尔,日期,二进制,范围类型)。 同时每个文档都有一个 Unique ID ,可以自己指定 ID ,或者通过 ElasticSearch 自 动生成。所以严格来说,es 中存储的文档是一种半结构化的数据。
 
映射
映射( mapping )定义了每个字段的类型、字段所使用的分词器等。 get /nandao_index/_mapping
可以显式映射,由我们在索引映射中进行预先定义;也可以动态映射,在添 加文档的时候,由 es 自动添加到索引,这个过程不需要事先在索引进行字段数 据类型匹配等等,es 会自己推断数据类型。 既然说到了字段类型,当然就离不开字段的数据类型了。
文档字段
文档中的一个字段 field 就相当于关系型数据库中的一列 column ,那么它肯 定有数据类型,es 提供的数据类型包括至少有:
 
数据类型
核心数据类型 # 字符串类型: string ,字符串类还可被分为 text keyword 类型,如果我 们让 es 自动映射数据,那么 es 会把字符串定义为 text ,并且还加了一个 keyword 类型字段。 text 文本数据类型,用于索引全文值的字段。使用文本数据类型的字段,它 们会被分词,在索引之前将字符串转换为单个术语的列表( 倒排索引 ) ,分词过程 允许 ES 搜索每个全文字段中的单个单词。什么情况适合使用 text ,只要不具备 唯一性的字符串一般都可以使用 text 。 keyword,关键字数据类型,用于索引结构化内容的字段。使用 keyword 类 型的字段,其不会被分析,给什么值就原封不动地按照这个值索引,所以关键字 字段只能按其确切值进行搜索。什么情况下使用 keyword ,具有唯一性的字符串,
例如:电子邮件地址、 MAC 地址、身份证号、状态代码 ... 等等。
# 数字型数据类型: long integer short byte double float
# 日期类型: date
# 布尔类型: boolean
复杂数据类型
# 数组:无需专门的数据类型
# 对象数据类型:单独的 JSON 对象
# 嵌套数据类型: nested ,关于 JSON 对象的数组
地理数据类型:
# 地理点数据类型
# 地理形状数据类型
专门数据类型:
# IPv4 数据类型
# 单词计数数据类型 token_count
我们结合前面的映射来看看:
创建一个新的索引 put /open-soft
显式映射
put /open-soft/_mapping { "properties" : { "corp" : { "type" : "text" },"lang" : { "type" : "text" },"name" : {
"type" : "text" } } }
索引或者说入库一个文档 ,注意这个文档的字段,比我们显示映射的字段要多个 star 字段:
put /open-soft/_doc/1
{
"name": "Apache Hadoop",
"lang": "Java",
"corp": "Apache",
"stars":200
}
 
通过 get /open-soft/_mapping ,我们可以看到 es 自动帮我们新增了 stars 这 个字段。
修改映射 ,增加一个新的字段:
put/open-soft/_mapping{
  "properties": {
    "year": {
      "type": "integer"
    }
  }
}
 
数组
不需要特殊配置,一个字段如果被配置为基本数据类型,就是天生支持数组 类型的。任何字段都可以有 0 个或多个值,但是在一个数组中数据类型必须一样。 比如:
put /open-soft/_doc/2
{
"name": ["Apache Activemq","Activemq Artemis"],
"lang": "Java",
"corp": "Apache",
"stars":[500,200]
}
是没问题的,但是如果:
put /open-soft/_doc/3
{
"name": ["Apache Kafka"],
"lang": "Java",
"corp": "Apache",
"stars":[500,"kafka"]
}
则会出错。
 
对象
JSON 文档是有层次结构的,一个文档可能包含其他文档,如果一个文档包 含其他文档,那么该文档值是对象类型,其数据类型是对象。当然 ElasticSearch 中是没有所谓对象类型的,比如:
put /open-soft/_doc/object
{
  "name": [
    "Apache ShardingSphere"
  ],
  "lang": "Java",
  "corp": "JingDong",
  "stars": 400,
  "address": {
    "city": "BeiJing",
    "country": "亦庄"
  }
}
 
 
 
对象类型可以在定义索引的映射关系时进行指定。
多数据类型
如果说数组允许你使用同一个设置索引多项数据,那么多数据类型允许使用 不同的设置,对同一项数据索引多次。带来的好处就是可以同一文本有多种不同 的索引方式,比如一个字符串类型的字段,可以使用 text 类型做全文检索,使用 keyword 类型做聚合和排序。我们可以看到 es 的动态映射生成的字段类型里, 往往字符串类型都使用了多数据类型。当然,我们一样也可以自己定义:
put /open-soft/_mapping
{
  "properties": {
    "name": {
      "type": "text",
      "fields": {
        "raw": {
          "type": "keyword"
        },
        "length": {
          "type": "token_count",
          "analyzer": "standard"
        }
      }
    }
  }
}
在上面的代码里,我们使用 "fields" 就把 name 字段扩充为多字段类型,为 name 新增了两个子字段 raw length raw 设置类型为 keyword length 设置类 型为 token_count ,告诉 es 这个字段在保存还需要做词频统计。 通过 fields 字段设置的子字段 raw length ,在我们添加文档时,并不需要 单独设置值,他们 name 共享相同的值,只是 es 会以不同的方式处理字段值。 同样在检索文档的时候,它们也不会显示在结果中,所以它们一般都是在检索中 以查询条件的形式出现,以减少检索时的性能开销。
 
字段参数
在上面的代码里出现了 analyzer 这个词,这是什么?这个叫字段参数,和 type 一样,可以用来对字段进行配置。常用的字段参数和作用如下:
analyzer 指定分词器。elasticsearch 是一款支持全文检索的分布式存储系统,对于 text 类型的字段,首先会使用分词器进行分词,然后将分词后的词根一个一个存储在 倒排索引中,后续查询主要是针对词根的搜索。 analyzer 该参数可以在每个查询、每个字段、每个索引中使用,其优先级如 下(越靠前越优先):
1 、字段上定义的分词器
2 、索引配置中定义的分词器
3 、默认分词器 (standard)
normalizer
规范化,主要针对 keyword 类型,在索引该字段或查询字段之前,可以先对 原始数据进行一些简单的处理,然后再将处理后的结果当成一个词根存入倒排索 引中,默认为 null ,比如:
PUT index
{
  "settings": {
    "analysis": {
      "normalizer": {
        "my_normalizer": {  //1
          "type": "custom",
          "char_filter": [
            
          ],
          "filter": [
            "lowercase",
            "asciifolding"
          ]  //2
        }
      }
    }
  },
  "mappings": {
    "_doc": {
      "properties": {
        "foo": {
          "type": "keyword",
          "normalizer": "my_normalizer"  //3
        }
      }
    }
  }
}
代码 1 :首先在 settings 中的 analysis 属性中定义 normalizer
代码 2 :设置标准化过滤器,示例中的处理器为小写、 asciifolding
代码 3 :在定义映射时,如果字段类型为 keyword ,可以使用 normalizer
引用定义好的 normalizer
boost
权重值,可以提升在查询时的权重,对查询相关性有直接的影响,其默认值 为 1.0 。其影响范围为词根查询 (team query), 对前缀、范围查询。 5.0 版本后已废 止。
coerce
数据不总是我们想要的,由于在转换 JSON body 为真正 JSON 的时候 , 整型数 字 5 有可能会被写成字符串 "5" 或者浮点数 5.0 ,这个参数可以将数值不合法的部 分去除。默认为 true 。 例如:将字符串会被强制转换为整数、浮点数被强制转换为整数。
例如存在如下字段类型:
"number_one": {
"type": "integer"
}
声明 number_one 字段的类型为数字类型,那是否允许接收“ 6 ”字符串形 式的数据呢?因为在 JSON 中,“ 6 ”用来赋给 int 类型的字段,也是能接受的, 默认 coerce true ,表示允许这种赋值,但如果 coerce 设置为 false ,此时 es 只能接受不带双引号的数字,如果在 coerce=false 时,将“ 6 ”赋值给 number_one 时会抛出类型不匹配异常。
copy_to
copy_to 参数允许您创建自定义的 _all 字段。换句话说,多个字段的值可以 复制到一个字段中。
例如, first_name last_name 字段可以复制到 full_name 字段如下 :
PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "first_name": {
          "type": "text",
          "copy_to": "full_name"
        },
        "last_name": {
          "type": "text",
          "copy_to": "full_name"
        },
        "full_name": {
          "type": "text"
        }
      }
    }
  }
}
表示字段 full_name 的值来自 first_name + last_name
关于 copy_to 重点说明:
1 、字段的复制是原始值。
2 、同一个字段可以复制到多个字段,写法如下:“ copy_to”: [ “field_1”, “field_2” ]
doc_values
Doc values 的存在是因为倒排索引只对某些操作是高效的。 倒排索引的优 势 在于查找包含某个项的文档,而对于从另外一个方向的相反操作并不高效, 即:确定哪些项是否存在单个文档里,聚合需要这种次级的访问模式。
对于以下倒排索引:
 
 
如果我们想要获得所有包含 brown 的文档的词的完整列表,倒排索引是根据 项来排序的,所以我们首先在词项列表中找到 brown ,然后扫描所有列,找到包 含 brown 的文档。我们可以快速看到 Doc_1 Doc_2 包含 brown 这个 token 然后,对于聚合部分,我们需要找到 Doc_1 Doc_2 里所有唯一的词项。 用倒 排索引做这件事情代价很高: 我们会迭代索引里的每个词项并收
Doc_1 Doc_2 列里面 token 。这很慢而且难以扩展:随着词项和文档的数量 增加,执行时间也会增加。 Doc values 通过转置两者间的关系来解决这个问题。倒排索引将词项映射到包 含它们的文档,doc values 将文档映射到它们包含的词项:
 
 
 
当数据被转置之后,想要收集到 Doc_1 Doc_2 的唯一 token 会非常容易。获 得每个文档行,获取所有的词项,然后求两个集合的并集。 doc_values 缺省是 true ,即是开启的,并且只适用于非 text 类型的字段。
dynamic
是否允许动态的隐式增加字段。在执行 index api 或更新文档 API 时,对于 _source 字段中包含一些原先未定义的字段采取的措施,根据 dynamic 的取值, 会进行不同的操作: true,默认值,表示新的字段会加入到类型映射中。 false,新的字段会被忽略,即不会存入 _souce 字段中,即不会存储新字段, 也无法通过新字段进行查询。 strict,会显示抛出异常,需要新使用
put mapping api 先显示增加字段映射。
enabled
是否建立索引,默认情况下为 true es 会尝试为你索引所有的字段,但有时 候某些类型的字段,无需建立索引,只是用来存储数据即可。也就是说, ELasticseaech 默认会索引所有的字段, enabled 设为 false 的字段, elasicsearch 会 跳过字段内容,该字段只能从_source 中获取,但是不可搜。只有映射类型 (type) 和 object 类型的字段可以设置 enabled 属性。
eager_global_ordinals
表示是否提前加载全局顺序号。 Global ordinals 是一个建立在 doc values 和 fielddata 基础上的数据结构 , 它为每一个精确词按照字母顺序维护递增的编号。 每一个精确词都有一个独一无二的编号 并且 精确词 A 小于精确词 B 的编号 . Global ordinals 只支持 keyword text 型字段,在 keyword 字段中 , 默认是启 用的 而在 text 型字段中 只有 fielddata 和相关属性开启的状态下才是可用的。
fielddata
为了解决排序与聚合, elasticsearch 提供了 doc_values 属性来支持列式存储, 但 doc_values 不支持 text 字段类型。因为 text 字段是需要先分析(分词),会 影响 doc_values 列式存储的性能。 es 为了支持 text 字段高效排序与聚合,引入了一种新的数据结构 (fielddata) , 使用内存进行存储。默认构建时机为第一次聚合查询、排序操作时构建,主要存 储倒排索引中的词根与文档的映射关系,聚合,排序操作在内存中执行。因此 fielddata 需要消耗大量的 JVM 堆内存。一旦 fielddata 加载到内存后,它将永久 存在。通常情况下,加载 fielddata 是一个昂贵的操作,故默认情况下, text 字段的 字段默认是不开启 fielddata 机制。在使用 fielddata 之前请慎重考虑为什么要开 启 fielddata
format
JSON 文档中,日期表示为字符串。 Elasticsearch 使用一组预先配置的格式 来识别和解析这些字符串,并将其解析为 long 类型的数值 ( 毫秒 ) ,支持自定义格 式,也有内置格式。
比如:
PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "date": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss"
        }
      }
    }
  }
}
elasticsearch 为我们内置了大量的格式,如下: epoch_millis 时间戳,单位,毫秒,范围受限于 Java Long.MIN_VALUE Long.MAX_VALUE 。 epoch_second 时间戳,单位,秒,范围受限于 Java 的限制 Long.MIN_VALUE Long. MAX_VALUE 除以 1000 (一秒中的毫秒数)。 date_optional_time 或者 strict_date_optional_time 日期必填,时间可选,其支持的格式如下:date-opt-time = date-element ['T' [time-element] [offset]]
date-element = std-date-element | ord-date-element | week-date-element
std-date-element = yyyy ['-' MM ['-' dd]]
ord-date-element = yyyy ['-' DDD]
week-date-element = xxxx '-W' ww ['-' e]
time-element = HH [minute-element] | [fraction]
minute-element = ':' mm [second-element] | [fraction]
second-element = ':' ss [fraction]
比如 "yyyy-MM-dd" "yyyyMMdd" "yyyyMMddHHmmss"
"yyyy-MM-ddTHH:mm:ss" "yyyy-MM-ddTHH:mm:ss.SSS"
"yyyy-MM-ddTHH:mm:ss.SSSZ" 格式,不支持常用的 "yyyy-MM-dd HH:mm:ss" 等格式。
注意, "T" "Z" 是固定的字符。
tips :如果看到“ strict_ ”前缀的日期格式要求,表示 date_optional_time 的 严格级别,这个严格指的是年份、月份、天必须分别以 4 位、 2 位、 2 位表示, 不足两位的话第一位需用 0 补齐。
basic_date
其格式表达式为 : yyyyMMdd
basic_date_time
其格式表达式为: yyyyMMdd T HHmmss.SSSZ
basic_date_time_no_millis
其格式表达式为: yyyyMMdd T HHmmssZ
basic_ordinal_date
4 位数的年 + 3 (day of year) ,其格式字符串为 yyyyDDD
basic_ordinal_date_time
其格式字符串为 yyyyDDD T HHmmss.SSSZ
basic_ordinal_date_time_no_millis
其格式字符串为 yyyyDDD T HHmmssZ
basic_time
其格式字符串为 HHmmss.SSSZ
basic_time_no_millis
其格式字符串为 HHmmssZ
basic_t_time
其格式字符串为’ T HHmmss.SSSZ
basic_t_time_no_millis
其格式字符串为’ T HHmmssZ
basic_week_date 其格式字符串为 xxxx W wwe 4 为年 ,然后用’ W , 2 week of year
(所在年里周序号) 1 day of week
basic_week_date_time
其格式字符串为 xxxx W wwe T HH:mm:ss.SSSZ.
basic_week_date_time_no_millis
其格式字符串为 xxxx W wwe T HH:mm:ssZ.
date
其格式字符串为 yyyy-MM-dd
date_hour
其格式字符串为 yyyy-MM-dd T HH
date_hour_minute
其格式字符串为 yyyy-MM-dd T HH:mm
date_hour_minute_second
其格式字符串为 yyyy-MM-dd T HH:mm:ss
date_hour_minute_second_fraction
其格式字符串为 yyyy-MM-dd T HH:mm:ss.SSS
date_hour_minute_second_millis
其格式字符串为 yyyy-MM-dd T HH:mm:ss.SSS
date_time
其格式字符串为 yyyy-MM-dd T HH:mm:ss.SSS
date_time_no_millis
其格式字符串为 yyyy-MM-dd T HH:mm:ss
hour
其格式字符串为 HH
hour_minute
其格式字符串为 HH:mm
hour_minute_second
其格式字符串为 HH:mm:ss
hour_minute_second_fraction
其格式字符串为 HH:mm:ss.SSS
hour_minute_second_millis
其格式字符串为 HH:mm:ss.SSS
ordinal_date
其格式字符串为 yyyy-DDD, 其中 DDD day of year
ordinal_date_time
其格式字符串为 yyyy-DDD T HH:mm:ss.SSSZZ, 其中 DDD day of year ordinal_date_time_no_millis
其格式字符串为 yyyy-DDD T HH:mm:ssZZ
time
其格式字符串为 HH:mm:ss.SSSZZ
time_no_millis
其格式字符串为 HH:mm:ssZZ
t_time
其格式字符串为’ T HH:mm:ss.SSSZZ
t_time_no_millis
其格式字符串为’ T HH:mm:ssZZ
week_date
其格式字符串为 xxxx-'W ww-e,4 位年份, ww 表示 week of year e 表示 day
of week
week_date_time
其格式字符串为 xxxx-'W ww-e T HH:mm:ss.SSSZZ
week_date_time_no_millis
其格式字符串为 xxxx-'W ww-e T HH:mm:ssZZ
weekyear
其格式字符串为 xxxx
weekyear_week
其格式字符串为 xxxx-'W ww, 其中 ww week of year
weekyear_week_day
其格式字符串为 xxxx-'W ww-e, 其中 ww week of year,e day of week
year
其格式字符串为 yyyy
year_month
其格式字符串为 yyyy-MM
year_month_day
其格式字符串为 yyyy-MM-dd
ignore_above
ignore_above 用于指定字段索引和存储的长度最大值,超过最大值的会被忽 略。
ignore_malformed
ignore_malformed 可以忽略不规则数据,对于 login 字段,有人可能填写的 是 date 类型,也有人填写的是邮件格式。给一个字段索引不合适的数据类型发 生异常,导致整个文档索引失败。如果 ignore_malformed 参数设为 true ,异常会 被忽略,出异常的字段不会被索引,其它字段正常索引。
index
index 属性指定字段是否索引,不索引也就不可搜索,取值可以为 true 或者 false,缺省为 true
index_options
index_options 控制索引时存储哪些信息到倒排索引中,,用于搜索和突出显 示目的。
docs 只存储文档编号
freqs 存储文档编号和词项频率。
positions 文档编号、词项频率、词项的位置被存储 offsets 文档编号、词项频率、词项的位置、词项开始和结束的字符位置都 被存储。
fields
fields 可以让同一文本有多种不同的索引方式,比如一个 String 类型的字段, 可以使用 text 类型做全文检索,使用 keyword 类型做聚合和排序。
norms
norms 参数用于标准化文档,以便查询时计算文档的相关性。 norms 虽然对 评分有用,但是会消耗较多的磁盘空间,如果不需要对某个字段进行评分,最好 不要开启 norms
null_value
一般来说值为 null 的字段不索引也不可以搜索, null_value 参数可以让值为 null 的字段显式的可索引、可搜索。
PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "status_code": {
          "type": "keyword",
          "null_value": "NULL"
        }
      }
    }
  }
}
PUT my_index/my_type/1
{
"status_code": null
}
PUT my_index/my_type/2
{
"status_code": []
}
GET my_index/_search
{
  "query": {
    "term": {
      "status_code": "NULL"
    }
  }
}
文档 1 可以被搜索到,因为 status_code 的值为 null ,文档 2 不可以被搜索 到,因为 status_code 为空数组,但是不是 null
position_increment_gap
文本数组元素之间位置信息添加的额外值。
举例,一个字段的值为数组类型: "names": [ "John Abraham", "Lincoln Smith"] 为了区别第一个字段和第二个字段,Abraham Lincoln 在索引中有一个间 距,默认是 100 。例子如下,这是查询” Abraham Lincoln ”是查不到的:
PUT my_index/groups/1
{
"names": [ "John Abraham", "Lincoln Smith"]
}
GET my_index/groups/_search
{
  "query": {
    "match_phrase": {
      "names": {
        "query": "Abraham Lincoln"
      }
    }
  }
}
指定间距大于 10 0 可以查询到:
GET my_index/groups/_search
{
  "query": {
    "match_phrase": {
      "names": {
        "query": "Abraham Lincoln",
        "slop": 101
      }
    }
  }
}
想要调整这个值,在 mapping 中通过 position_increment_gap 参数指定间距 即可。
properties
Object 或者 nested 类型,下面还有嵌套类型,可以通过 properties 参数指定。
比如:
PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "manager": {
          "properties": {
            "age": {
              "type": "integer"
            },
            "name": {
              "type": "text"
            }
          }
        },
        "employees": {
          "type": "nested",
          "properties": {
            "age": {
              "type": "integer"
            },
            "name": {
              "type": "text"
            }
          }
        }
      }
    }
  }
}
对应的文档结构:
PUT my_index/my_type/1
{
  "region": "US",
  "manager": {
    "name": "Alice White",
    "age": 30
  },
  "employees": [
    {
      "name": "John Smith",
      "age": 34
    },
    {
      "name": "Peter Brown",
      "age": 26
    }
  ]
}
search_analyzer
通常,在索引时和搜索时应用相同的分析器,以确保查询中的术语与反向索 引中的术语具有相同的格式,如果想要在搜索时使用与存储时不同的分词器,则 使用 search_analyzer 属性指定,通常用于 ES 实现即时搜索 (edge_ngram)
similarity
指定相似度算法,其可选值: BM25 当前版本的默认值,使用 BM25 算法。 classic 使用 TF/IDF 算法,曾经是 es,lucene 的默认相似度算法。 boolean 一个简单的布尔相似度,当不需要全文排序时使用,并且分数应该只基于查 询条件是否匹配。布尔相似度为术语提供了一个与它们的查询boost相等的分数。
store
默认情况下,字段值被索引以使其可搜索,但它们不存储。这意味着可以查 询字段,但无法检索原始字段值。通常这并不重要。字段值已经是_source 字段 的一部分,该字段默认存储。如果您只想检索单个字段或几个字段的值,而不是 整个_source ,那么这可以通过字段过滤上下文 source filting context 来实现。 在某些情况下,存储字段是有意义的。例如,如果您有一个包含标题、日期 和非常大的内容字段的文档,您可能只想检索标题和日期,而不需要从大型 _source 字段中提取这些字段,可以将标题和日期字段的 store 定义为 ture
term_vector
Term vectors 包含分析过程产生的索引词信息,包括 : 索引词列表 每个索引词的位置(或顺序) 索引词在原始字符串中的原始位置中的开始和结束位置的偏移量。 term vectors 会被存储,索引它可以作为一个特使的文档返回。
term_vector 可取值:
no
不存储 term_vector 信息,默认值。
yes
只存储字段中的值。
with_positions
存储字段中的值与位置信息。
with_offsets
存储字段中的值、偏移量
with_positions_offsets
存储字段中的值、位置、偏移量信息。
 
元字段 meta-fields
一个文档根据我们定义的业务字段保存有数据之外,它还包含了元数据字段 (meta-fields ) 。元字段不需要用户定义,在任一文档中都存在,有点类似于数据库 的表结构数据。在名称上有个显著的特征,都是以下划线“_ ”开头。
我们可以看看: get /open-soft/_doc/1
大体分为五种类型:身份(标识)元数据、索引元数据、文档元数据、路由 元数据以及其他类型的元数据,当然不是每个文档这些元字段都有的。
身份(标识)元数据
_index: 文档所属索引 , 自动被索引,可被查询,聚合,排序使用,或者脚 本里访问
_type :文档所属类型,自动被索引,可被查询,聚合,排序使用,或者脚
本里访问
_id :文档的唯一标识,建索引时候传入 ,不被索引,可通过 _uid 被查询, 脚本里使用,不能参与聚合或排序
_uid :由 _type _id 字段组成,自动被索引 ,可被查询,聚合,排序使用, 或者脚本里访问,6.0.0 版本后已废止。
索引元数据
_all : 自动组合所有的字段值,以空格分割,可以指定分器词索引,但是整 个值不被存储,所以此字段仅仅能被搜索,不能获取到具体的值。6.0.0 版本后 已废止。
_field_names :索引了每个字段的名字,可以包含 null 值,可以通过 exists 查询或 missing 查询方法来校验特定的字段
文档元数据
_source : 一个 doc 的原生的 json 数据,不会被索引,用于获取提取字段 值 ,启动此字段,索引体积会变大,如果既想使用此字段又想兼顾索引体积, 可以开启索引压缩。
_source 是可以被禁用的,不过禁用之后部分功能不再支持,这些功能包括: 部分 update api 、运行时高亮搜索结果 索引重建、修改 mapping 以及分词、索引升级 debug 查询或者聚合语句
索引自动修复
_size : 整个 _source 字段的字节数大小,需要单独安装一个 mapper-size 插 件才能展示。
路由元数据
_routing : 一个 doc 可以被路由到指定的 shard 上。
其他
_meta :一般用来存储应用相关的元信息。 例如:
put /open-soft/_mapping
{
  "_meta": {
    "class": "cn.enjoyedu.User",
    "version": {
      "min": "1.0",
      "max": "1.3"
    }
  }
}
今天 到此结束,下一篇我们详细分析 Elasticsearch 索引和文档的管理
 
 
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寅灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值