elasticsearch 字段类型的索引、字段类型修改、字段类型、分页、排序、分组、聚合
Elasticsearch 支持多种数据类型,用于处理和存储不同格式的文档数据。主要的数据类型分为三大类:核心数据类型、复杂数据类型和特殊数据类型。
京东把 Elasticsearch 用得真牛逼!日均5亿订单查询完美解决!
Elasticsearch 在各大互联网公司大量真实的应用案例
总结一下ElasticSearch在的实践,
1.大数据量实时搜索
2.不作为写库使用,仅用来做亿级数据查询
elasticsearch对不同类型的字段所使用的索引
Elasticsearch 对不同类型的字段使用不同的索引策略和结构。这些策略旨在针对不同类型的数据提供最优的存储和查询性能。下面是 Elasticsearch 中常见字段类型及其索引策略的概述:
文本字段类型
text
: 用于全文搜索。字段会被分词器处理,生成一系列词项(tokens),并存储在倒排索引中。每个词项都有一个文档ID列表(posting list),表示包含该词项的文档。keyword
: 用于精确匹配和聚合。字段不会被分词器处理,而是作为完整的字符串存储。每个字段值被视为一个词条,并存储在倒排索引中。
数值字段类型
integer
、long
、float
、double
: 数值字段会被建立索引,存储在有序的结构中,便于快速查找和范围查询。数值字段的索引通常使用特殊的编码方式,如 Delta 编码或可变整数编码,以节省存储空间。
日期字段类型
date
: 日期字段会被转换为毫秒数(自 Unix 纪元以来的毫秒数),并存储在索引中。这使得日期字段可以像数值字段一样进行排序和范围查询。
布尔字段类型
boolean
: 布尔字段被存储为true
或false
,并建立索引以便快速查找。
二进制字段类型
binary
: 二进制数据字段通常不被建立索引,而是存储在文档中。如果需要搜索二进制数据,可以使用特殊的技术,如倒排索引的扩展或使用外部索引服务。
复合字段类型
object
、nested
: 这些字段类型用于嵌套文档。object
类型字段会被扁平化并存储在主文档中,而nested
类型字段则作为独立的文档存储,并建立索引,以便支持嵌套文档的独立搜索和聚合。
地理空间字段类型
geo_point
: 地理坐标字段会被建立索引,支持基于距离的查询和地理位置的聚合。geo_shape
: 地理形状字段会被建立索引,支持基于形状的查询,如多边形内的文档查询。
特殊字段类型
ip
: IP 地址字段会被转换为整数,并建立索引,以便进行快速查找和范围查询。token_count
: 计算给定text
字段中的词项数量。通常不建立索引,但可以用于聚合。
示例
下面是一个包含不同字段类型的索引映射示例:
PUT /example_index
{
"mappings": {
"properties": {
"title": { "type": "text" }, // 分词后存储
"author": { "type": "keyword" }, // 不分词存储
"content": { "type": "text" },
"published_date": { "type": "date" },
"views": { "type": "integer" },
"is_published": { "type": "boolean" },
"location": { "type": "geo_point" },
"comments": { "type": "nested", "properties": {
"author": { "type": "keyword" },
"body": { "type": "text" },
"date": { "type": "date" }
}}
}
}
}
总结
text
和keyword
类型的字段使用倒排索引。- 数值、日期、布尔和 IP 类型的字段使用有序结构,便于快速查找和范围查询。
- 复合类型如
object
和nested
类型字段根据具体类型和配置使用不同的索引策略。 - 地理空间类型的字段使用专门的索引结构,支持基于位置的查询。
希望这些信息对你有所帮助!如果有更具体的问题或需要进一步的帮助,请随时提问。
对于数值、日期、布尔和 IP 类型的字段,Elasticsearch 使用了高效的内部数据结构来支持快速查找和范围查询。虽然这些内部结构不像 MySQL 的 InnoDB 引擎那样使用 B+ 树,但它们仍然实现了类似的高效性能。
Elasticsearch 的内部数据结构
Elasticsearch 基于 Lucene 构建,Lucene 使用了多种高效的数据结构来存储和索引数据。对于数值、日期、布尔和 IP 类型的字段,Lucene 使用了以下数据结构和技术:
-
Packed Block: 用于存储数值类型的字段。这是一种高效的压缩存储技术,可以将整数和浮点数以位级压缩的形式存储,节省存储空间并加快检索速度。
-
DocValues: 用于数值、日期、布尔和 IP 类型的字段。DocValues 是一种高效的列式存储技术,允许快速访问文档的值。这些值通常以排序的方式存储,以便于执行范围查询和聚合。
-
BitSet: 用于布尔类型的字段。BitSet 是一种高效的位数组结构,可以快速标记哪些文档包含特定的布尔值。
-
Prefix Coded: 用于日期类型的字段。这是一种高效的编码方式,可以将日期值以压缩的形式存储,同时支持快速的范围查询。
与 B+ 树的关系
B+ 树是一种广泛应用于数据库索引的数据结构,它允许高效地进行范围查询。虽然 Elasticsearch 和 Lucene 不直接使用 B+ 树,但它们使用的 DocValues 和 Packed Block 等技术在功能上与 B+ 树相似,都能够支持高效的范围查询。
示例
假设你有一个包含 integer
类型字段的索引:
PUT /example_index
{
"mappings": {
"properties": {
"age": {
"type": "integer"
}
}
}
}
插入一些文档:
PUT /example_index/_doc/1
{
"age": 25
}
PUT /example_index/_doc/2
{
"age": 30
}
PUT /example_index/_doc/3
{
"age": 20
}
查询年龄在 20 到 30 之间的文档:
GET /example_index/_search
{
"query": {
"range": {
"age": {
"gte": 20,
"lte": 30
}
}
}
}
总结
- Elasticsearch 使用 DocValues 和 Packed Block 等技术来支持数值、日期、布尔和 IP 类型的字段。
- 这些技术在功能上与 B+ 树类似,能够支持高效的范围查询。
- Elasticsearch 的内部数据结构和算法设计旨在提供高性能的查询和聚合操作。
希望这些信息对你有所帮助!如果有更具体的问题或需要进一步的帮助,请随时提问。
elasticsearch有哪些数据类型,
Elasticsearch 支持多种数据类型,用于处理和存储不同格式的文档数据。主要的数据类型分为三大类:核心数据类型、复杂数据类型和特殊数据类型。
1. 核心数据类型
text
:用于全文搜索的文本数据。数据会经过分词器处理,用于全文索引。keyword
:用于结构化数据的精确匹配,适合存储不能分词的文本,如标签、用户名、状态等。numeric
(数值类型):long
:64 位带符号整数。integer
:32 位带符号整数。short
:16 位带符号整数。byte
:8 位带符号整数。double
:64 位双精度浮点数。float
:32 位单精度浮点数。half_float
:16 位半精度浮点数。scaled_float
:以缩放因子存储浮点数,适合需要精确度控制的数值数据。
date
:用于存储日期类型数据。支持多种日期格式和时间戳。boolean
:布尔类型,值为true
或false
。binary
:用于存储二进制数据(Base64 编码)。
2. 复杂数据类型
object
:JSON 对象类型,可以包含多个子字段。Elasticsearch 会为每个子字段创建单独的索引。nested
:类似于object
,但支持更复杂的嵌套查询。这种类型的数据可以作为独立的文档进行索引和查询。array
:可以存储相同类型的多个值。数组可以包含text
、keyword
、date
、boolean
、numeric
类型的元素。
3. 特殊数据类型
geo_point
:用于存储地理位置的经纬度坐标,可以用于地理位置查询。geo_shape
:用于存储复杂的地理形状数据(如多边形、线条等),适合空间关系查询。ip
:用于存储 IPv4 和 IPv6 地址,可以用于 IP 地址范围查询。completion
:用于自动完成建议功能的特定类型,适合为用户提供实时建议。token_count
:用于存储分词后的 token 数量,通常与分析器结合使用。percolator
:用于存储查询本身,以支持文档与查询的反向匹配。range
:用于存储数值、日期、IP 范围,如integer_range
、float_range
、long_range
、date_range
、ip_range
。
这些数据类型使得 Elasticsearch 能够灵活地处理各种结构化和非结构化数据,满足不同的查询和分析需求。
elasticsearch 会对int, data, keyword, boolean等字段创建索引吗
Elasticsearch 会对 int
、date
、keyword
、boolean
等字段类型创建索引,但索引的方式和目的略有不同:
-
int
(数值类型):- 数值字段(如
integer
、long
、short
等)会被索引,以便支持范围查询、排序等操作。
- 数值字段(如
-
date
(日期类型):- 日期字段会被索引,用于支持日期范围查询、排序等操作。
-
keyword
(关键字类型):- 关键字字段会被索引,用于精确匹配查询,如过滤和聚合操作。
keyword
类型适合存储结构化的、不可分词的文本数据,如标签、用户名等。
- 关键字字段会被索引,用于精确匹配查询,如过滤和聚合操作。
-
boolean
(布尔类型):- 布尔字段会被索引,用于支持基于布尔值的查询。
在 Elasticsearch 中,这些字段会自动生成倒排索引或其他适合的数据结构(如 BKD tree 用于数值和日期类型)来加速查询和排序操作。索引机制使得 Elasticsearch 可以高效处理各种类型的数据查询需求。
elasticsearch 会对int, data, keyword, boolean等字段创建索引,是默认行为吗,需要加额外配置吗
Elasticsearch 默认会对 int
(数值类型)、date
(日期类型)、keyword
(关键字类型)、boolean
(布尔类型)等字段创建索引,无需额外配置。这是 Elasticsearch 的默认行为,旨在提供高效的查询能力。
具体解释如下:
-
int
(数值类型):- 数值类型字段(如
integer
、long
、short
等)默认情况下会被索引,以便支持范围查询和排序。
- 数值类型字段(如
-
date
(日期类型):- 日期类型字段默认情况下会被索引,用于支持日期范围查询和排序。
-
keyword
(关键字类型):- 关键字类型字段默认情况下会被索引,以便进行精确匹配查询、过滤和聚合。
-
boolean
(布尔类型):- 布尔类型字段默认情况下会被索引,用于布尔值查询。
不创建索引的情况:
如果你不希望对某些字段创建索引,可以在映射(mapping)中明确设置这些字段的 index
属性为 false
。例如:
{
"mappings": {
"properties": {
"field_name": {
"type": "keyword",
"index": false
}
}
}
}
这种配置告诉 Elasticsearch 不对 field_name
字段创建索引,但字段的原始数据仍然会存储在 _source
中。
额外配置的情况:
默认的索引行为适用于大多数场景,但如果有特定需求(如自定义分析器、禁用索引、定义字段格式等),则需要在映射中进行额外配置。
已创建的文档,字段类型不能更改是吗
是的,在 Elasticsearch 中,一旦文档的字段类型在索引中被定义并使用,就无法直接修改字段类型。这是因为字段类型影响到数据的存储方式和索引方式,如果修改字段类型,可能导致现有数据与新定义的字段类型不兼容。
解决方法:
如果需要修改字段类型,可以考虑以下几种方案:
-
创建新索引:
- 创建一个新索引,并在新的映射(mapping)中定义所需的字段类型。
- 将旧索引的数据重新索引到新索引中。
- 完成后,将应用程序切换到新索引。
-
使用动态模板(Dynamic Templates):
- 如果你在动态映射时发现字段类型被错误定义,可以使用动态模板来细化字段类型的自动推断逻辑。
-
通过脚本重新索引:
- 使用
_reindex
API,通过脚本对数据进行转换,将数据从旧索引迁移到新索引,同时应用新的字段类型。
- 使用
-
创建多字段(Multi-fields):
- 如果希望对同一字段以多种不同的方式进行索引,可以使用多字段的机制,而不需要更改现有的字段类型。例如,一个字段可以同时被索引为
text
和keyword
类型。
- 如果希望对同一字段以多种不同的方式进行索引,可以使用多字段的机制,而不需要更改现有的字段类型。例如,一个字段可以同时被索引为
{
"mappings": {
"properties": {
"field_name": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
注意事项:
- 修改字段类型可能会影响查询性能和存储效率,因此在做出这些更改之前,最好仔细规划和测试。
- 如果有大量的数据,重新索引的过程可能需要一定时间,可能需要计划在低流量时间段进行。
Elasticsearch对分页查询的支持
Elasticsearch 提供了几种方式来实现分页查询。以下是常用的分页方法:
1. 基于 from
和 size
的分页
这是 Elasticsearch 最基本的分页方式,类似于 SQL 中的 LIMIT
和 OFFSET
。
from
: 指定结果集的起始位置,默认值是0
。size
: 指定返回结果的数量,默认值是10
。
{
"query": {
"match": {
"field_name": "value"
}
},
"from": 0,
"size": 10
}
优点: 简单直接,适合小规模分页查询。
缺点: 当分页数很大时(如数千或数万条数据),性能会显著下降,因为 Elasticsearch 仍需要扫描和排序所有文档。
2. 基于 search_after
的分页
search_after
是另一种分页方式,它通过使用上一次查询结果中的排序值来继续分页。这种方式适合深度分页。
- 需要对查询结果进行排序(
sort
字段必须指定)。 - 使用上一次结果的排序值作为
search_after
参数。
{
"query": {
"match": {
"field_name": "value"
}
},
"size": 10,
"sort": [
{"field_name": "asc"},
{"_id": "asc"}
],
"search_after": ["last_sort_value", "last_doc_id"]
}
优点: 避免了深度分页的性能问题。
缺点: 不能直接跳过多页,需要从第一页开始逐页获取。
当多个文档具有相同的排序值时,可以通过增加一个辅助排序字段来解决分页问题。
如果 search_after 不适用,可以考虑使用 from 和 size 进行分页,尽管这种方法可能不太适合大数据集。
3. 基于 scroll
的分页
scroll
API 用于处理大量数据的分页查询,适合对全量数据进行处理(如批量导出、分析等)。
- 创建
scroll
上下文,通过scroll
参数来获取下一个批次的数据。 - 需要注意清理
scroll
上下文,避免占用资源。
{
"query": {
"match": {
"field_name": "value"
}
},
"size": 100,
"scroll": "1m"
}
然后使用 _scroll_id
获取下一批数据:
{
"scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAA=",
"scroll": "1m"
}
优点: 适合大规模数据的逐步处理,且不会影响集群性能。
缺点: 只能用于一次性任务,不适合实时的应用分页场景。
1m 是 scroll ID 的保持时间,表示你有一分钟的时间来滚动查询结果。
“size”: 10 是每次查询返回的文档数量。
4. 基于 search
API 的 slice
分片分页
slice
允许将查询分割为多个并行执行的子查询,适合大数据量时的并行处理。
{
"query": {
"match": {
"field_name": "value"
}
},
"slice": {
"id": 0,
"max": 10
},
"size": 100
}
优点: 适合并行处理,提升处理速度。
缺点: 需要额外的逻辑来合并不同 slice
的结果。
Elasticsearch 提供了一个名为 slice
的特性,用于更高效地处理分页查询。slice
特性允许你将大的搜索请求分割成多个较小的请求,并将这些请求并行执行。这可以显著提高处理大规模数据集时的性能。
使用 slice 分页
slice
特性通过以下参数来配置:
slice.shard_size
: 指定每个分片上返回的最大文档数量。这类似于size
参数。slice.id
: 指定当前请求的分片 ID。slice.total
: 指定总共有多少个分片请求。
示例
假设你想要对一个索引进行分页查询,每页返回 10 条文档,使用 slice
特性来分割请求。
-
初始化查询:
- 首先,定义查询参数,包括排序字段、
slice.shard_size
、slice.id
和slice.total
。 - 示例命令如下:
GET /example_index/_search { "size": 0, // 不返回文档,仅用于获取总数 "query": { "match_all": {} } }
这个查询用于获取索引中总共有多少文档。
- 首先,定义查询参数,包括排序字段、
-
计算分片数量:
- 假设你想要每页返回 10 条文档,并且知道索引中共有多少文档,你可以计算出需要多少个分片请求。
- 例如,如果有 1000 条文档,每页返回 10 条,则总共需要 100 个分片请求。
-
执行分片查询:
- 对于每个分片请求,你需要指定
slice.shard_size
、slice.id
和slice.total
。 - 示例命令如下:
GET /example_index/_search { "slice": { "shard_size": 10, // 每个分片返回的文档数量 "id": 0, // 当前分片的 ID "total": 100 // 总共分片的数量 }, "sort": ["_doc"], // 排序字段 "query": { "match_all": {} } }
这个命令会返回第一个分片的 10 条文档。
- 对于每个分片请求,你需要指定
-
合并结果:
- 你需要将所有分片请求的结果合并起来,以得到完整的分页结果。
注意事项
- 并发执行:
slice
特性支持并发执行多个分片请求,这意味着你可以在客户端并行发起这些请求,以提高查询效率。
- 结果合并:
- 你需要在客户端合并所有分片请求的结果,以获得最终的分页结果。
- 排序字段:
- 确保所有分片请求使用相同的排序字段,以确保分页的一致性。
- 分片大小:
slice.shard_size
应该与每页返回的文档数量相匹配。
总结
slice
特性允许你将大的搜索请求分割成多个较小的请求,并将这些请求并行执行。- 通过合理设置
slice.shard_size
、slice.id
和slice.total
,可以有效地实现分页查询。 - 最终结果需要在客户端合并所有分片请求的结果。
希望这些信息对你有所帮助!如果有更具体的问题或需要进一步的帮助,请随时提问。
总结
from
和size
:适用于小规模数据集的简单分页。search_after
:适用于深度分页且不需要跳页的场景。scroll
:适用于处理大数据量的批量导出、分析任务。slice
:适用于并行处理大数据量任务。
根据应用场景的不同选择合适的分页方法,可以提高查询性能和用户体验。
Elasticsearch查询字段允许哪些操作符
在 Elasticsearch 中,查询字段可以使用多种操作符来构建灵活的查询条件。这些操作符在不同的查询类型中可能略有不同。以下是一些常见的操作符和它们的使用方式:
1. 布尔操作符(Boolean Operators)
must
: 必须匹配的条件,类似于逻辑与 (AND
)。must_not
: 必须不匹配的条件,类似于逻辑非 (NOT
)。should
: 应该匹配的条件,类似于逻辑或 (OR
)。满足该条件会提高文档的相关性得分,但不是必须的。filter
: 类似于must
,但不会影响文档的相关性得分。
{
"bool": {
"must": [
{"match": {"field_name": "value"}}
],
"must_not": [
{"term": {"field_name": "unwanted_value"}}
],
"should": [
{"match": {"other_field": "value"}}
],
"filter": [
{"term": {"status": "active"}}
]
}
}
2. 比较操作符(Comparison Operators)
range
: 用于执行范围查询,支持操作符如gt
(大于),gte
(大于等于),lt
(小于),lte
(小于等于)。
{
"range": {
"field_name": {
"gte": 10,
"lt": 20
}
}
}
3. 存在操作符(Existence Operator)
exists
: 检查字段是否存在。
{
"exists": {
"field": "field_name"
}
}
4. 通配符和正则表达式(Wildcard and Regular Expressions)
wildcard
: 允许使用通配符*
(匹配零个或多个字符) 和?
(匹配单个字符) 进行匹配。
{
"wildcard": {
"field_name": "val*"
}
}
regexp
: 使用正则表达式匹配字段值。
{
"regexp": {
"field_name": "val[0-9]+"
}
}
5. 全文搜索操作符(Full-Text Search Operators)
match
: 匹配文本字段,可以使用operator
参数指定逻辑与 (AND
) 或逻辑或 (OR
)。
{
"match": {
"field_name": {
"query": "search text",
"operator": "and"
}
}
}
match_phrase
: 匹配完整的短语或词组。
{
"match_phrase": {
"field_name": "exact phrase"
}
}
multi_match
: 对多个字段进行匹配。
{
"multi_match": {
"query": "search text",
"fields": ["field1", "field2"]
}
}
6. 模糊搜索操作符(Fuzzy Search Operator)
fuzzy
: 用于模糊匹配,允许在查询词上有一定的拼写错误。
{
"fuzzy": {
"field_name": {
"value": "search text",
"fuzziness": "AUTO"
}
}
}
7. 短语前缀匹配(Phrase Prefix Match)
match_phrase_prefix
: 匹配以指定短语为前缀的字段值。
{
"match_phrase_prefix": {
"field_name": "start of phrase"
}
}
8. 脚本查询(Script Query)
script
: 允许使用脚本语言(如 Painless)来进行复杂的条件判断。
{
"script": {
"script": "doc['field_name'].value > 10"
}
}
这些操作符可以在不同类型的查询中组合使用,以构建复杂的查询条件,从而满足各种数据检索需求。
int类型的相等比较呢
在 Elasticsearch 中,对 int
(或其他数值类型,如 long
、float
、double
等)进行相等比较,可以使用 term
查询。这种查询用于精确匹配字段的值,包括数值类型。
示例:
假设你有一个名为 age
的字段,你希望查找所有 age
等于 25
的文档,可以使用以下查询:
{
"query": {
"term": {
"age": 25
}
}
}
解释:
term
查询: 直接匹配字段的精确值。在这个例子中,它将查找所有age
字段等于25
的文档。
注意事项:
term
查询适用于数值类型、布尔类型和关键字类型的字段。如果对text
类型的字段使用term
查询,Elasticsearch 会尝试匹配整个分词后的 token,因此一般不用于全文搜索。- 对于数值类型的字段,
term
查询的匹配是精确的,不会进行任何范围或模糊匹配。
Elasticsearch的match操作符
在 Elasticsearch 中,match
操作符用于进行全文搜索,是最常用的查询之一。match
查询适合处理 text
类型的字段,因为它会对查询内容进行分词,然后根据分词后的词条进行匹配和评分。
基本用法
{
"query": {
"match": {
"field_name": "search text"
}
}
}
功能与特点
-
分词查询:
match
查询会根据字段的分析器(Analyzer)对查询字符串进行分词,然后在索引中查找分词后的词条。- 例如,针对
"quick brown fox"
这样的查询字符串,Elasticsearch 可能会将其分词为["quick", "brown", "fox"]
,然后查询这三个词条。
-
操作符:
- 默认情况下,
match
查询会使用OR
操作符,即只要分词后的一个词条匹配,文档就会被返回。 - 可以通过设置
operator
参数来控制匹配行为:"or"
(默认):任意一个词条匹配即返回文档。"and"
:所有词条都必须匹配才返回文档。
- 默认情况下,
{
"query": {
"match": {
"field_name": {
"query": "quick brown fox",
"operator": "and"
}
}
}
}
- 匹配模式:
match_phrase
:用于匹配一个完整的短语,而不是分词后的独立词条。match_phrase_prefix
:匹配以特定短语开头的字段值。
{
"query": {
"match_phrase": {
"field_name": "quick brown fox"
}
}
}
- 模糊匹配:
- 可以通过设置
fuzziness
参数来实现模糊匹配,允许少量的拼写错误或字符替换。
- 可以通过设置
{
"query": {
"match": {
"field_name": {
"query": "quikc",
"fuzziness": "AUTO"
}
}
}
}
- 零次或更多次出现:
- 通过
minimum_should_match
参数,你可以指定必须匹配的最少词条数量。
- 通过
{
"query": {
"match": {
"field_name": {
"query": "quick brown fox",
"minimum_should_match": 2
}
}
}
}
- Boost(权重):
- 你可以使用
boost
参数提高某些查询条件的权重,使其在评分时更具影响力。
- 你可以使用
{
"query": {
"match": {
"field_name": {
"query": "quick brown fox",
"boost": 2.0
}
}
}
}
适用场景
match
查询适合进行全文搜索,当你需要在一个文本字段中查找包含某些关键词的文档时,非常适合使用。- 如果你希望进行精确匹配(如查找特定的标识符、标签等),
term
查询可能更合适。
match
查询是 Elasticsearch 中处理自然语言和文本搜索的核心工具之一,能够在大规模文本数据中快速找到相关内容。
match_phrase:用于匹配一个完整的短语,而不是分词后的独立词条。于term的区别
match_phrase
和 term
都是 Elasticsearch 中常用的查询类型,但它们的用途和工作方式有很大的区别。
match_phrase
查询
- 用途: 用于在全文搜索中匹配一个完整的短语。
- 工作方式:
- 分词:
match_phrase
查询会先对输入的查询字符串进行分词,然后检查这些词条是否以相同的顺序在字段中出现,并且它们之间的距离(即词之间的间隔)符合预期。 - 短语匹配: 它不仅仅是寻找包含所有词条的文档,还要求这些词条在文档中的顺序和位置与查询中一致。
- 分词:
示例
假设你有一个字段 content
,其内容为 "the quick brown fox jumps over the lazy dog"
。
-
查询
{"match_phrase": {"content": "quick brown"}}
会找到这个文档,因为"quick brown"
这个短语确实按顺序出现在字段中。 -
查询
{"match_phrase": {"content": "brown quick"}}
则不会匹配,因为虽然文档包含这两个词,但它们的顺序与查询不一致。
term
查询
- 用途: 用于精确匹配一个词条或数值。通常适用于精确匹配结构化数据(如标识符、关键字、数值)。
- 工作方式:
- 不分词:
term
查询不会对输入的查询字符串进行分词。它将查询值视为一个整体,并直接在索引中查找完全匹配该值的文档。
- 不分词:
示例
假设你有一个字段 status
,其内容为 "active"
。
- 查询
{"term": {"status": "active"}}
会找到这个文档,因为它直接查找与"active"
完全匹配的词条。 - 查询
{"term": {"status": "Active"}}
不会匹配,因为term
查询是区分大小写的。
总结
-
match_phrase
查询:- 用于全文搜索,匹配完整的短语,考虑词条顺序和间隔。
- 会对查询字符串进行分词,然后检查词条是否按顺序出现在文档中。
-
term
查询:- 用于精确匹配,不分词,直接查找完全匹配的词条或数值。
- 适合查找不分词的字段(如
keyword
类型字段)或数值字段。
在选择使用 match_phrase
还是 term
时,关键在于你希望搜索的内容是否需要进行分词和顺序匹配。对于自然语言文本搜索,match_phrase
更为合适;而对于精确匹配的需求,term
更为合适。
elasticsearch对排序的支持
Elasticsearch 对排序和分页提供了强大的支持,能够帮助开发者有效地组织和访问搜索结果。以下是关于排序和分页功能的详细说明:
1. 排序(Sorting)
Elasticsearch 允许对查询结果进行排序,支持多种数据类型和排序方式。
排序字段和类型
text
: 一般不会直接排序text
字段,而是使用keyword
字段,text
字段可以通过多字段(multi-fields
)设置支持排序。keyword
: 支持按字母顺序排序。numeric
: 可以按数值大小排序(如integer
,long
,float
,double
等)。date
: 可以按日期时间排序。boolean
: 可以按布尔值排序,false
为 0,true
为 1。geo_point
: 可以按距离排序。
排序方式
- 升序 (
asc
): 按从小到大的顺序排序。 - 降序 (
desc
): 按从大到小的顺序排序。
示例:排序的基本用法
假设我们有一个字段 price
和 date
,我们希望首先按 price
降序排列,然后按 date
升序排列:
{
"query": {
"match_all": {}
},
"sort": [
{"price": {"order": "desc"}},
{"date": {"order": "asc"}}
]
}
多字段排序
Elasticsearch 支持对多个字段进行排序,排序顺序按字段的顺序依次进行。
自定义排序脚本
你可以使用 script
字段来自定义排序逻辑,适用于复杂的排序场景:
{
"query": {
"match_all": {}
},
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "doc['field_name'].value * params.factor",
"params": {
"factor": 1.1
}
},
"order": "asc"
}
}
}
更多推荐
所有评论(0)