你的唯一短语数越多,搜索就越慢。 12.2 处理 Null 值 回到我们早期的示例,在文档中有一个多值的字段 tags,一个文档可能包含一个或多个标签,或根本没有标签。...如果一个字段没有值,它是怎么储存在倒排索引中的? 这是一个取巧的问题,因为答案是它根本没有存储。...倒排索引是标记和包含它们的文档的一个简单列表。假如一个字段不存在,它就没有任何标记,也就意味着它无法被倒排索引的数据结构表达出来。 本质上来说,null,[](空数组)和 [null] 是相等的。...它们都不存在于倒排索引中! 显然,这个世界却没有那么简单,数据经常会缺失字段,或包含空值或空数组。为了应对这些情形,Elasticsearch 有一些工具来处理空值或缺失的字段。...独立的过滤缓存 每个过滤器都被独立计算和缓存,而不管它们在哪里使用。如果两个不同的查询使用相同的过滤器,则会使用相同的字节集。同样,如果一个查询在多处使用同样的过滤器,只有一个字节集会被计算和重用。
字段类型也可以是复杂类型,一个字段包含其他子文档或者数组。 映射 所有文档写进索引之前都会先进行分析,如何将输入的文本分割为词条、哪些词条又会被过滤,这种行为叫做映射(mapping)。...如果删除一条不存在的数据,会响应404: 2.5.5、搜索数据 根据id搜索数据 Get 127.0.0.1:9200/hello/user/1001 #响应数据 { "_index": "hello...q=age:20 2.5.6、DSL搜索 Elasticsearch提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。...如果字段需要进行过 滤(比如查找已发布博客中status属性为published的文章)、排序、聚合。keyword类型的字段只能通过精 确值搜索到。...* 查询语句会询问每个文档的字段值与特定值的匹配程度如何。 一条查询语句会计算每个文档与查询语句的相关性,会给出一个相关性评分 _score,并且 按照相关性对匹配到的文档进行排序。
当我们在处理搜索业务时候,需求往往是灵活多变的,有时候我们需要精确匹配,有时候我们又需要全文检索,而有时候,我们又想匹配度高而且还能全文检索,这似乎是精确匹配和模糊匹配一个妥协的策略,没错这就是搜索引擎出现的目的...,以往的数据库是没法解决这种问题的,数据库只能回答有,没有,存在,不存在,并不能在有和没有之间做一个完美的妥协,比如说能把最匹配最相关的结果放在topN,仅靠like模糊查询是解决不了这种问题的。...Apache Lucene这个强大的全文检索核心包,提供了搜索引擎的核心组件,通过相关性评分算法(VSM/BM25),出色的了解决了相关性匹配问题,当然Solr和ElasticSearch构建在Lucene...不管总term有多少个,如果查询词分词后的term个数小于3,那么就以最小的这个term数为基准进行查询 语法二:-2 允许返回的结果里面,最多有2个不匹配term,其他的必须都匹配,这是一种反向用法...-25% 反向设置,返回的结果里面最多有25%的不匹配 语法五:3如果一个字段分词后的term数,小于等于3,则要求全部匹配,如果大于3,则要求90%的匹配度 语法六:2<-25%
3.有查询条件 3.1 叶子条件查询(单字段查询条件) 3.1.1 模糊匹配 模糊匹配主要是针对文本类型的字段,文本类型的字段会对内容进行分词,对查询时,也会对搜索条件进行分词,然后通过倒排索引查找到匹配的数据...3.1.2 精确匹配 term : 单个条件相等 terms : 单个字段属于某个值数组内的值 range : 字段属于某个范围内的值 exists : 某个字段的值是否存在 ids : 通过ID批量查询...等叶子条件为参数的 注:以上参数,当只有一个搜索条件时,must等对应的是一个对象,当是多个条件时,对应的是一个数组 3.3 连接查询(多文档合并查询) 父子文档查询:parent/child 嵌套文档查询...,需要指定字段名,但是输入会进行分词,比如"hello world"会进行拆分为hello和world,然后匹配,如果字段中包含hello或者world,或者都包含的结果都会被查询出来,也就是说match...当保存数据"hello world"时,elasticsearch会对字段内容进行分词,"hello world"会被分成hello和world,不存在"hello world",因此这里的查询结果会为空
为了方便在全文文本字段中进行这些类型的查询,Elasticsearch首先对文本分析(analyzes),然后使用结果建立一个倒排索引 倒排索引 Elasticsearch使用一种叫做倒排索引(inverted...如果我们加入简单的相似度算法(similarity algorithm),计算匹配单词的数目,这样我们就可以说第一个文档比第二个匹配度更高——对于我们的查询具有更多相关性。...但是这样我们仍旧查不到像Quick,Dog这样的词 不过,如果我们使用相同的标准化规则处理查询字符串的content字段,查询将变成"+quick +fox",这样就可以匹配到两个文档。...如果你改变了字段映射,那已经被索引的数据将错误并且不能被正确的搜索到。...如果你创建一个新字段,这个字段索引了一个数组,Elasticsearch将使用第一个值的类型来确定这个新字段的类型。 空字段 数组可以是空的。这等价于有零个值。
官方网站:https://www.elastic.co/guide/index.html 5.搜索——最基本工具 空搜索 搜索API的最基础的形式是没有指定任何查询的空搜索 ,它简单地返回集群中所有索引下的所有文档...hits ,它 包含 total 字段来表示匹配到的文档总数,并且一个 hits 数组包含所查询结果的前十个文档。...分页 在之前的 空搜索 中说明了集群中有 14 个文档匹配了(empty)query 。 但是在 hits 数组中只有 10 个文档。如何才能看到其他的文档?...这暗示数组中所有的值必须是相同数据类型的。你不能将日期和字符串混在一起。如果你通过索引数组来创建新的域,Elasticsearch会用数组中第一个值的数据类型作为这个域的类型。...但是,数组是以多值域索引的—可以搜索,但是无序的。 在搜索的时候,你不能指定 “第一个” 或者 “最后一个”。 更确切的说,把数组想象成装在袋子里的值 。 空域 当然,数组可以为空。
5.处理null值 回想在之前例子中,有的文档有名为 tags (标签)的字段,它是个多值字段, 一个文档可能有一个或多个标签,也可能根本就没有标签。...简单的说,一个倒排索引只是一个 token 列表和与之相关的文档信息,如果字段不存在,那么它也不会持有任何 token,也就无法在倒排索引结构中表现。...最终,这也就意味着 ,null, [](空数组)和[null] 所有这些都是等价的,它们无法存于倒排索引中。 显然,世界并不简单,数据往往会有缺失字段,或有显式的空值或空数组。...当选择合适的 null_value 空值的时候,需要保证以下几点: 它会匹配字段的类型,我们不能为一个 date 日期字段设置字符串类型的 null_value 。...first 和 last 都是空,那么 name 这个命名空间才会被认为不存在。
图1 在默认的分析器将字符串分解为词条后,随后的搜索匹配了那些词条 分析过程生成了4个词条,即late、night、with和elasticsearch。查询的字符串经过同样的处理。...因为查询生成的late词条和文档生成的late词条匹配了,所以文档1匹配上了搜索。...如果只想严格匹配某个字段,就像SQL中的where name = 'late',应该将整个字段作为一个单词对待。ES对文本类型的keyword字段不做分析,而是将整个字符串当做单独的词条进行索引。...如果不指定字段名,系统默认将会在_all上搜索,下面的两条命令是等价的,返回相同的结果: curl '172.16.1.127:9200/get-together/_search?...它并不考虑这些字段之前的值,也不考虑这些字段之前是否存在。如果之前整个文档是不存在的,那么更新操作会失败,并提示文档缺失。
这是如何运作的?首先,映射包含某个类型中当前索引的所有文档的所有字段。但不是所有的文档必须要有所有的字段。同样,如果一篇新索引的文档拥有一个映射中尚不存在的字段,ES会自动地将新字段加入映射。...数组之前包含了几项统计数据: "total" : 10, "max_score" : 1.4880564 total表示匹配文档的总数,max_score是这些匹配文档的最高得分。...Denver" } } ] 结果中包括每个匹配文档所属的索引、类型、它的ID、得分,以及搜索查询中所指定的字段的值。...查询中使用了_source=name,location_event.name。如果结果中某个指定字段的值为空,缺省没有该字段的定义,就像结果中没有location_event.name字段。...例如,如果搜索“Elasticsearch san Francisco”,ES默认查询所有字段。
上面提到新增了一个昵称字段,但是历史数据中是没有这个字段,如果查询历史数据,则返回的数据中不会有这个字段,虽然查询不会报错,但是取值时,会返回 null。...文档存储型 比如 MongoDB,存储的 JSON 格式的文档,解决了关系型数据库的表约束的问题,比如查询不存在的字段会报错。...如下图所示: [搜索日志] 传统的关系型的数据库主要是通过索引来进行快速查询,但如果放在全文搜索的场景下,就行不通了。...我们来看看为什么关系型数据库很难做到高效的全文搜索: 因为在全文搜索中,搜索的条件是可以随意排列组合的,比如字段 A、B、C,可以排列成 6 种,如果要用索引来支持快速查询的话,则需要创建多个索引,这是非常麻烦的...模糊匹配只能用 like 查询,而 like 查询是整表扫描,效率是非常低的。
查询字段会被索引和分析,在执行之前将每个字段的分词器(或搜索分词器)应用于查询字符串。...这怎么可能,既然是精确匹配,一个字段也不可能有两个不同的值。 1.3.3 range query 匹配某一范围内的数据型、日期类型或者字符串型字段的文档,注意只能查询一个字段,不能作用在多个字段上。...以下文档会匹配上面的查询: 文档 说明 {"user":"jane"} 有user字段,且不为空 {"user":""} 有user字段,值为空字符串 {"user":"-"} 有user字段,值不为空...所以使用term查询可以精确匹配,但设置为text,则不一定——如果有添加分词器,则可以搜索到;如果没有,而是使用默认的分词器,只是将其分为一个一个的字,就不会被搜索到。...Note3:所以根据上面的提示,一般纯数组比较适合存放标签类的数据,就像上面的案例一样,同时字段类型设置为keyword,而不是text,搜索时进行精确匹配就好了。
使用 PUT 方法提交文档时,如果指定的 id 已经存在,则该文档将被更新;如果不存在则该文档将被创建。...": "asc" } ], "from": 10, "size": 10 } 指定字段查询 如果要在字段中搜索特定字词,可以使用match 查询address 字段中包含 mill 或者 lane..."bool": 查询类型,表示执行一个布尔查询,它可以包含多个条件。 "must": 这是一个数组,包含了必须匹配的条件。在这里,我们要求文档的"age"字段必须匹配值"40"。..."must_not": 这也是一个数组,包含了不能匹配的条件。在这里,我们要求文档的"state"字段不能匹配值"ID"。..."must": 这是一个数组,包含了必须匹配的条件。在这里,我们要求文档的"state"字段必须匹配值"ND",即北达科他州。 "filter": 这是一个数组,包含了过滤条件,这些条件用于排除文档。
期间,Luke还展示如何通过Elasticsearch实现模糊匹配。 以下为译文: 介绍 假设你正在运行MongoDB。太好了,现在已经可以为基于数据库的所有查询进行精确匹配了。...当然,如果只想在post标题和内容中进行文本搜索,我们可以使用Elasticsearch的字段选项来限制字段。通过这个方法,我们能最小化所复制的数据量: ?...弹性的搜索 现在,我们准备使用Elasticsearch在我们的数据集上实现模糊匹配查询,因为它来自于MongoDB。由于我们直接从Reddit的网站输出内容,因此根本无法预测从数据集中获得的结果。...以“kitten”的搜索为例,以下为实现代码: ? 由于我们正在进行一个模糊搜索,我们甚至可以搜索一个并不存在的词,例如kiten。...模糊参数决定了下一次查询字段匹配的最大“edit distance”, prefix_length参数则需求结果必须匹配查询的第一个字母。
上面提到新增了一个昵称字段,但是历史数据中是没有这个字段,如果查询历史数据,则返回的数据中不会有这个字段,虽然查询不会报错,但是取值时,会返回 null。...文档存储型 比如 MongoDB,存储的 JSON 格式的文档,解决了关系型数据库的表约束的问题,比如查询不存在的字段会报错。...如下图所示: 搜索日志 传统的关系型的数据库主要是通过索引来进行快速查询,但如果放在全文搜索的场景下,就行不通了。...我们来看看为什么关系型数据库很难做到高效的全文搜索: 因为在全文搜索中,搜索的条件是可以随意排列组合的,比如字段 A、B、C,可以排列成 6 种,如果要用索引来支持快速查询的话,则需要创建多个索引,这是非常麻烦的...模糊匹配只能用 like 查询,而 like 查询是整表扫描,效率是非常低的。 之前我写过一篇 Elasticsearch 原理的:《别只会搜日志了,求你懂点原理吧》,通过倒排索引实现高效的全文检索。
默认按照相关性得分排序,即每个文档跟查询的匹配程度。...短语搜索 找出一个属性中的独立单词是没有问题的,但有时候想要精确匹配一系列单词或者短语 。...这些聚合并非预先统计,而是从匹配当前查询的文档中即时生成。...然而,这是一个内部细节,我们的应用程序根本不应该关心分片,对于应用程序而言,只需知道文档位于一个 索引 内。 Elasticsearch 会处理所有的细节。...如果你的主数据库已经有了版本号 或一个能作为版本号的字段值比如 timestamp ,那么你就可以在 Elasticsearch 中通过增加 version_type=external 到查询字符串的方式重用这些相同的版本号
查找多个精确值 term查询对单个值非常有用,如果要查找价格字段值为20或30的文档时,可以使用多个term查询,也可以使用terms查询。...在索引数组数据时,如果需要根据数组数量匹配,可以多索引一个字段,用来保存数量。...处理Null值 null, [] (空数组)和 [null] 所有这些都是无法存于倒排索引中。针对这些字段,在ES中是什么都不存的。 在查询时,需要进行处理。...存在查询: 用exists关键字查询 缺失查询: 用missing查询 对于空值,感觉需要在业务上进行处理,尽量避免添加空值null或字符串null的情况。...Elasticsearch 会基于使用频次自动缓存查询。如果一个非评分查询在最近的 256 次查询中被使用过(次数取决于查询类型),那么这个查询就会作为缓存的候选。
在实际业务中,如果我们要对字段的内容进行全文搜索,可以使用text类型;如果要聚合查询或者精准匹配,则尽量使用keyword类型。...结果返回了包含"河北省"和"江苏省"的文档信息3.利用tagname字段的子字段(keyword类型)进行匹配查询#利用tagname字段的子字段(keyword类型)进行匹配查询GET myindex...(keyword类型)进行了不分词搜索,需要保证搜索的内容和字段存储的内容完全匹配,所以从当前索引库中匹配到了数据。...当然,如果事先已经定义了字段类型,在写数据时以数组形式写入,ES也会将该类型转为数组。...那么,数组类型的数据如何搜索呢?#数组类型的字段适用于元素类型的搜索方式,也就是说,数组元素适用于什么搜索,数组字段就适用于什么搜索。
出现这个问题归根结底是因为对于Elasticsearch的底层索引原理以及各个查询搜索方式的不了解,在Elasticsearch中仅仅字符串相关的查询就有19个之多,如果不弄清楚查询语句的工作方式,应用可能就不会按照我们预想的方式运作...如果你的app想要添加一个搜索框,为用户提供搜索操作,并且数据量很大用MySQL会造成慢查询想改用Elasticsearch,那么我相信这篇文章会给你带来很大的帮助。...exists 返回所有指定字段不为空的文档,比如这个字段对应的值是null或者[]或者没有为这个字段建立索引。...这个方法可以用来搜索没有被索引的值或者不存在的值。 fuzzy fuzzy查询是一种模糊查询,会根据检索词和检索字段的编辑距离(Levenshtein Distance)来判断是否匹配。...用户可以生成一个特别复杂的查询语句,里面可能包含通配符、多字段匹配等等。在搜索之前ES会检查查询语句的语法,如果有语法错误会直接报错。
,默认不存储,且不可搜索 范围类型 INTERSECTS :默认的匹配模式,只要搜索值与字段值有交集即可匹配到 WITHIN:字段值需要完全包含在搜索值之内,也就是字段值是搜索值的子集才能匹配 CONTAINS...导致这个文档错误地匹配对 alice 和 smith 的查询 如果最开始就把user设置为 nested 嵌套对象呢?...第一次查询时完整加载这个字段所有 Segment 中的倒排索引到内存中 如果我们有一些 5 GB 的索引段,并希望加载 10 GB 的 fielddata 到内存中,这个过程可能会要数十秒 将 fielddate..." } # 搜索hello,结果为空,而不是3条!!...参数对评分很有用,但需要占用大量的磁盘空间 如果不需要计算字段的评分,可以取消该字段 norms 的功能 position_increment_gap 与 proximity queries(近似查询
领取专属 10元无门槛券
手把手带您无忧上云