1、倒排索引 Inverted index2、基本概念3、Elasticsearch索引4、文档 (document)5、映射6、文档字段
6.1 数据类型
6.1.1 核心数据类型6.1.2 复杂数据类型6.1.3 地理数据类型6.1.4 专门数据类型 6.2 数组6.3 对象6.4 多数据类型 7、字段参数
7.1 analyzer7.2 fields7.3 properties7.4 ignore_above 8、元字段 meta-fields
8.1 身份(标识)元数据8.2 索引元数据8.3 文档元数据8.4 路由元数据8.5 其他 1、倒排索引 Inverted index
将文档中包含的关键字全部提取处理,然后再将关键字和文档之间的对应关系保存起来,最后再对关键字本身做索引排序。用户在检索某一个关键字是,先对关键字的索引进行查找,再通过关键字与文档的对应关系找到所在文档。在存储在关系型数据库中的数据,需要我们事先分析将数据拆分为不同的字段,而在 es 这类的存储中,需要应用程序根据规则自动提取关键字,并形成对应关系。这些预先提取的关键字,在全文检索领域一般被称为 term(词项),文档的词项提取在 es 中被称为文档分析,这是全文检索很核心的过程,必须要区分哪些是词项,哪些不是,比如很多场景下,apple 和 apples 是同一个东西,望和看其实是同一个动作。比如现在有:
蜀道难(唐)李白 蜀道之难难于上青天,侧身西望长咨嗟。
静夜思(唐)李白 举头望明月,低头思故乡。
春台望(唐)李隆基 暇景属三春,高台聊四望。
鹤冲天(宋)柳永 黄金榜上,偶失龙头望。明代暂遗贤,如何向?未遂风云便,争不恣狂荡。何须论得丧?才子词人,自是白衣卿相。烟花巷陌,依约丹青屏障。幸有意中人,堪寻访。且恁偎红翠,风流事,平生畅。青春都一饷。忍把浮名,换了浅斟低唱!都有望字,于是我们可以这么保存
如果查哪个诗词中包含上,怎么办,上述的表格可以继续填入新的记录
上述诗词的中每个字都可以作为关键字,然后建立关键字和文档之间的对应关系,也就是标识关键字被哪些文档包含。 2、基本概念
比较关键的基本概念有索引、文档、映射、映射类型、文档字段概念,为了方便理解,可以和关系数据库中的相关概念进行个比对
3、Elasticsearch索引这里的映射类型在es7之后,就只保留一种类型为_doc,相当于在数据库中只存在一张表
Elasticsearch 索引是映射类型的容器。一个 Elasticsearch 索引非常像关系型世界的数据库,是独立的大量文档集合。
最基本的结构就是“keyword”和“PostingList”,Posting list 就是一个 int 的数组,存储了所有符合某个 term 的文档 id。它会保存每一个词项出现过的文档总数, 在对应的文档中一个具体词项出现的总次数,词项在文档中的顺序,每个文档的长度,所有文档的平均长度等相关信息。 4、文档 (document)
文档是 es 中所有可搜索数据的最小单位,比如日志文件中的日志项、一部电影的具体信息等等。文档会被序列化 JSON 格式保存到 ElasticSearch 中,JSON 对象由字段组成,每个字段都有对象的字段类型(字符串,数值,布尔,日期,二进制,范围类型)。同时每个文档都有一个 Unique ID,可以自己指定 ID,或者通过 ElasticSearch 自动生成。所以严格来说,es 中存储的文档是一种半结构化的数据。 5、映射
映射(mapping)定义了每个字段的类型、字段所使用的分词器等。可以显式映射,由我们在索引映射中进行预先定义;也可以动态映射,在添加文档的时候,由 es 自动添加到索引,这个过程不需要事先在索引进行字段数据类型匹配等等,es 会自己推断数据类型。 6、文档字段
文档中的一个字段 field 就相当于关系型数据库中的一列 column,那么它肯定有数据类型,es 提供的数据类型包括至少有: 6.1 数据类型 6.1.1 核心数据类型 字符串类型: string,字符串类还可被分为 text 和 keyword 类型,如果我们让 es 自动映射数据,那么 es 会把字符串定义为 text,并且还加了一个 keyword类型字段。
text 文本数据类型,用于索引全文值的字段。使用文本数据类型的字段,它们会被分词,在索引之前将字符串转换为单个术语的列表(倒排索引),分词过程允许 ES 搜索每个全文字段中的单个单词。什么情况适合使用 text,只要不具备唯一性的字符串一般都可以使用 text。
keyword,关键字数据类型,用于索引结构化内容的字段。使用 keyword 类型的字段,其不会被分析,给什么值就原封不动地按照这个值索引,所以关键字字段只能按其确切值进行搜索。什么情况下使用 keyword,具有唯一性的字符串,例如:电子邮件地址、MAC 地址、身份证号、状态代码…等等。数字型数据类型:long、integer、short、byte、double、float日期类型:date布尔类型:boolean 6.1.2 复杂数据类型 数组:无需专门的数据类型对象数据类型:单独的 JSON 对象嵌套数据类型:nested,关于 JSON 对象的数组 6.1.3 地理数据类型 地理点数据类型地理形状数据类型 6.1.4 专门数据类型 IPv4 数据类型单词计数数据类型 token_count 6.2 数组
不需要特殊配置,一个字段如果被配置为基本数据类型,就是天生支持数组类型的。任何字段都可以有 0 个或多个值,但是在一个数组中数据类型必须一样。
put /open-soft/_doc/2{ "name": [ "Apache Activemq", "Activemq Artemis" ], "lang": "Java", "corp": "Apache", "stars": [ 500, 200 ]}
6.3 对象JSON 文档是有层次结构的,一个文档可能包含其他文档,如果一个文档包含其他文档,那么该文档值是对象类型,其数据类型是对象。当然 ElasticSearch中是没有所谓对象类型的,比如:
put /open-soft/_doc/object{ "name": [ "Apache ShardingSphere" ], "lang": "Java", "corp": "JingDong", "stars": 400, "address": { "city": "BeiJing", "country": "亦庄" }}
对象类型可以在定义索引的映射关系时进行指定。 6.4 多数据类型
如果说数组允许你使用同一个设置索引多项数据,那么多数据类型允许使用不同的设置,对同一项数据索引多次。带来的好处就是可以同一文本有多种不同的索引方式,比如一个字符串类型的字段,可以使用 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 会以不同的方式处理字段值。同样在检索文档的时候,它们也不会显示在结果中,所以它们一般都是在检索中以查询条件的形式出现,以减少检索时的性能开销。 7、字段参数 7.1 analyzer
指定分词器。elasticsearch 是一款支持全文检索的分布式存储系统,对于 text类型的字段,首先会使用分词器进行分词,然后将分词后的词根一个一个存储在倒排索引中,后续查询主要是针对词根的搜索。analyzer 该参数可以在每个查询、每个字段、每个索引中使用,其优先级如下(越靠前越优先):
1、字段上定义的分词器
2、索引配置中定义的分词器
3、默认分词器(standard) 7.2 fields
fields 可以让同一文本有多种不同的索引方式,比如一个 String 类型的字段,可以使用 text 类型做全文检索,也可以使用 keyword 类型做聚合和排序。 7.3 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 } ]}
7.4 ignore_aboveignore_above 用于指定字段索引和存储的长度最大值,超过最大值的会被忽略。这是索引在静态设置中唯一能修改的参数。 8、元字段 meta-fields
一个文档根据我们定义的业务字段保存有数据之外,它还包含了元数据字段(meta-fields)。元字段不需要用户定义,在任一文档中都存在,有点类似于数据库的表结构数据。在名称上有个显著的特征,都是以下划线“_”开头。大体分为五种类型:身份(标识)元数据、索引元数据、文档元数据、路由元数据以及其他类型的元数据,当然不是每个文档这些元字段都有的。 8.1 身份(标识)元数据
_index:文档所属索引 , 自动被索引,可被查询,聚合,排序使用,或者脚本里访问_type:文档所属类型,自动被索引,可被查询,聚合,排序使用,或者脚本里访问_id:文档的唯一标识,建索引时候传入 ,不被索引,可通过_uid 被查询,脚本里使用,不能参与聚合或排序_uid:由_type 和_id 字段组成,自动被索引 ,可被查询,聚合,排序使用,或者脚本里访问,6.0.0 版本后已废止。 8.2 索引元数据
_all: 自动组合所有的字段值,以空格分割,可以指定分器词索引,但是整个值不被存储,所以此字段仅仅能被搜索,不能获取到具体的值。6.0.0 版本后已废止。_field_names:索引了每个字段的名字,可以包含 null 值,可以通过 exists查询或 missing 查询方法来校验特定的字段 8.3 文档元数据
_source : 一个 doc 的原生的 json 数据,不会被索引,用于获取提取字段值 ,启动此字段,索引体积会变大,如果既想使用此字段又想兼顾索引体积,可以开启索引压缩。_source 是可以被禁用的,不过禁用之后部分功能不再支持,这些功能包括:
部分 update api、运行时高亮搜索结果
索引重建、修改 mapping 以及分词、索引升级
debug 查询或者聚合语句
索引自动修复_size: 整个_source 字段的字节数大小,需要单独安装一个 mapper-size 插
件才能展示。 8.4 路由元数据
_routing: 一个 doc 可以被路由到指定的 shard 上。 8.5 其他
_meta:一般用来存储应用相关的元信息。
例如:
put /open-soft/_mapping{ "_meta": { "class": "cn.enjoyedu.User", "version": { "min": "1.0", "max": "1.3" } }}