8. 常见ES结构化搜索
8. 常见ES结构化搜索
赵洲洋mapping说明
mapping结构如下
1 | "某字段" : { |
term查询注意事项
在Elasticsearch中,term
查询用于对精确值进行匹配。对于字段类型的考虑,有两个关键点需要注意:
Text vs Keyword: 在Elasticsearch中,
text
类型的字段通常用于全文搜索,这些字段在索引时会被分词。而keyword
类型的字段用于精确值匹配,不会被分词。使用
keyword
字段进行term
查询: 虽然text
类型的字段理论上也可以用于term
查询,但通常不推荐这样做,因为text
字段上的term
查询会对字段的每个分词进行匹配,这通常不是预期的行为。相反,keyword
类型的字段非常适合用于term
查询,因为它们不会被分词。
如下,某字段
字段是一个text
类型的字段,但它还定义了一个名为keyword
的子字段。这意味着您可以使用某字段.keyword
来执行term
查询,以精确匹配特定的值。
因此,要对某字段
字段进行term
查询,您应该使用它的keyword
子字段,如下所示:
1 | { |
在这个查询中,某字段.keyword
将确保对该字段的精确值进行匹配。
如果在query.term
中直接使用text
类型的字段(比如某字段
)而不是它的.keyword
子字段,可能会导致查询不按预期工作。原因如下:
分词处理:
text
类型的字段在索引时会被分词。这意味着文本会被拆分成较小的单元(通常是单词)。当使用term
查询text
字段时,Elasticsearch会尝试将您提供的精确值与这些分词后的单元进行匹配。查询结果不准确:因为
text
字段被分词,所以term
查询可能会返回不符合预期的结果。例如,如果您试图精确匹配一个短语或一个包含多个词的字符串,查询可能会失败,因为整个短语或字符串作为一个整体并不存在于分词后的索引中。效率问题:对
text
字段使用term
查询通常也不是效率最高的做法。term
查询更适合用于未分词的keyword
字段。
综上所述,当需要进行精确匹配时,最好是使用字段的.keyword
子字段进行term
查询。如果直接对text
字段使用term
查询,可能不会得到正确或期望的结果。
ignore_above说明
在Elasticsearch中,ignore_above
是一个设置项,用于指定一个字符长度限制。当字段的类型被设置为 keyword
时,这个设置非常有用。它的主要作用如下:
字符长度限制:
ignore_above
设置一个最大字符长度。如果字段的值超过这个长度,Elasticsearch 将不会对该字段值进行索引。避免昂贵的操作:这个设置有助于避免对非常长的文本进行索引操作,这些操作可能是资源密集型的并且很少用于搜索。
影响索引和搜索:如果一个字段的值长度超过了
ignore_above
设置的长度,那么这个值不会被索引,也就无法通过搜索查询到。但这个值仍然会被存储在文档中,并且可以在返回文档时查看。用途示例:比如,如果你有一个字段通常包含短的编码或标识符,但偶尔会有非常长的值,你可能不想索引这些长值。在这种情况下,设置
ignore_above
可以保证只有短的、可能用于搜索的值被索引。
在字段设置中:
1 | "某字段" : { |
这意味着对于 某字段
字段的 keyword
子字段,任何超过 256 个字符的值都不会被索引。这有助于优化索引的性能,特别是当字段值可能非常长时。但请注意,这不会影响字段值的存储,在_source中返回的文档仍然会包含原始的未切割值。
must和filter区别
1 | { |
在Elasticsearch的查询中,filter
是 bool
查询的一部分,用于定义一个或多个过滤条件。filter
上的条件必须被满足,但它们不会影响搜索结果的相关性得分(scoring)。下面解释一下您提到的查询中的filter
的作用和是否必需:
作用:
filter
内的条件用于过滤结果集,以确保只返回满足这些条件的文档。在您的查询中,filter
里的term
查询是用来精确匹配字段id
的值为123
的文档。是否必需:
filter
不是必需的,它的使用取决于您的查询需求。如果您只需要返回所有文档而不关心特定条件,那么可以省略filter
。但如果您需要根据特定的条件来限制返回的文档,那么filter
就非常有用。与
must
的区别:在bool
查询中,must
和filter
都用于指定必须满足的条件,但它们的关键区别在于:must
:用于包含那些必须匹配的条件,这些条件会影响文档的相关性得分。filter
:用于包含那些必须匹配的条件,但这些条件不影响相关性得分。filter
通常用于范围查询、存在查询等,其中文档的得分不重要。
在您的查询示例中,match_all
配合filter
的使用意味着查询会返回所有文档,但只有那些id
字段值为123
的文档会被包含在结果中。如果您不需要基于特定条件过滤文档,那么您可以省略filter
部分。
如何查看es的分词效果
1 | POST http://IP:9200/索引名称/_analyze |
term精确查询
如果字段不是text,是基础类型,则不用加.keyword
1 | POST http://IP:9200/索引名称/_search |
term组合查询
简单组合
1 | POST http://IP:9200/索引名称/_search |
嵌套组合
1 | POST http://IP:9200/索引名称/_search |
terms多个值查询
注意1: key是terms而不是term,数组是中or的关系,类似mysql的in查询
注意2: term和terms的查询对象如果是array,则是【原始数据数组】包含【查询条件内容】的关系
1 | POST http://IP:9200/索引名称/_search |
范围查询
1 | POST http://IP:9200/索引名称/_search |
字段存在/非null查询
1 | POST http://IP:9200/索引名称/_search |
字段不存在/null查询
老版本的missing已经取消,需要使用bool的must_not结合exists使用
1 | POST http://IP:9200/索引名称/_search |