京东把 Elasticsearch 用得真牛逼!日均5亿订单查询完美解决!


Elasticsearch 在各大互联网公司大量真实的应用案例

总结一下ElasticSearch在的实践,
1.大数据量实时搜索
2.不作为写库使用,仅用来做亿级数据查询

elasticsearch对不同类型的字段所使用的索引

Elasticsearch 对不同类型的字段使用不同的索引策略和结构。这些策略旨在针对不同类型的数据提供最优的存储和查询性能。下面是 Elasticsearch 中常见字段类型及其索引策略的概述:

文本字段类型

  • text: 用于全文搜索。字段会被分词器处理,生成一系列词项(tokens),并存储在倒排索引中。每个词项都有一个文档ID列表(posting list),表示包含该词项的文档。
  • keyword: 用于精确匹配和聚合。字段不会被分词器处理,而是作为完整的字符串存储。每个字段值被视为一个词条,并存储在倒排索引中。

数值字段类型

  • integerlongfloatdouble: 数值字段会被建立索引,存储在有序的结构中,便于快速查找和范围查询。数值字段的索引通常使用特殊的编码方式,如 Delta 编码或可变整数编码,以节省存储空间。

日期字段类型

  • date: 日期字段会被转换为毫秒数(自 Unix 纪元以来的毫秒数),并存储在索引中。这使得日期字段可以像数值字段一样进行排序和范围查询。

布尔字段类型

  • boolean: 布尔字段被存储为 truefalse,并建立索引以便快速查找。

二进制字段类型

  • binary: 二进制数据字段通常不被建立索引,而是存储在文档中。如果需要搜索二进制数据,可以使用特殊的技术,如倒排索引的扩展或使用外部索引服务。

复合字段类型

  • objectnested: 这些字段类型用于嵌套文档。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" }
      }}
    }
  }
}

总结

  • textkeyword 类型的字段使用倒排索引。
  • 数值、日期、布尔和 IP 类型的字段使用有序结构,便于快速查找和范围查询。
  • 复合类型objectnested 类型字段根据具体类型和配置使用不同的索引策略。
  • 地理空间类型的字段使用专门的索引结构,支持基于位置的查询。

希望这些信息对你有所帮助!如果有更具体的问题或需要进一步的帮助,请随时提问。

对于数值、日期、布尔和 IP 类型的字段,Elasticsearch 使用了高效的内部数据结构来支持快速查找和范围查询。虽然这些内部结构不像 MySQL 的 InnoDB 引擎那样使用 B+ 树,但它们仍然实现了类似的高效性能。

Elasticsearch 的内部数据结构

Elasticsearch 基于 Lucene 构建,Lucene 使用了多种高效的数据结构来存储和索引数据。对于数值、日期、布尔和 IP 类型的字段,Lucene 使用了以下数据结构和技术:

  1. Packed Block: 用于存储数值类型的字段。这是一种高效的压缩存储技术,可以将整数和浮点数以位级压缩的形式存储,节省存储空间并加快检索速度。

  2. DocValues: 用于数值、日期、布尔和 IP 类型的字段。DocValues 是一种高效的列式存储技术,允许快速访问文档的值。这些值通常以排序的方式存储,以便于执行范围查询和聚合。

  3. BitSet: 用于布尔类型的字段。BitSet 是一种高效的位数组结构,可以快速标记哪些文档包含特定的布尔值。

  4. 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:布尔类型,值为 truefalse
  • binary:用于存储二进制数据(Base64 编码)。

2. 复杂数据类型

  • object:JSON 对象类型,可以包含多个子字段。Elasticsearch 会为每个子字段创建单独的索引。
  • nested:类似于 object,但支持更复杂的嵌套查询。这种类型的数据可以作为独立的文档进行索引和查询。
  • array:可以存储相同类型的多个值。数组可以包含 textkeyworddatebooleannumeric 类型的元素。

3. 特殊数据类型

  • geo_point:用于存储地理位置的经纬度坐标,可以用于地理位置查询。
  • geo_shape:用于存储复杂的地理形状数据(如多边形、线条等),适合空间关系查询。
  • ip:用于存储 IPv4 和 IPv6 地址,可以用于 IP 地址范围查询。
  • completion:用于自动完成建议功能的特定类型,适合为用户提供实时建议。
  • token_count:用于存储分词后的 token 数量,通常与分析器结合使用。
  • percolator:用于存储查询本身,以支持文档与查询的反向匹配。
  • range:用于存储数值、日期、IP 范围,如 integer_rangefloat_rangelong_rangedate_rangeip_range

这些数据类型使得 Elasticsearch 能够灵活地处理各种结构化和非结构化数据,满足不同的查询和分析需求。

elasticsearch 会对int, data, keyword, boolean等字段创建索引吗

Elasticsearch 会对 intdatekeywordboolean 等字段类型创建索引,但索引的方式和目的略有不同:

  1. int(数值类型)

    • 数值字段(如 integerlongshort 等)会被索引,以便支持范围查询、排序等操作。
  2. date(日期类型)

    • 日期字段会被索引,用于支持日期范围查询、排序等操作。
  3. keyword(关键字类型)

    • 关键字字段会被索引,用于精确匹配查询,如过滤和聚合操作。keyword 类型适合存储结构化的、不可分词的文本数据,如标签、用户名等。
  4. boolean(布尔类型)

    • 布尔字段会被索引,用于支持基于布尔值的查询。

在 Elasticsearch 中,这些字段会自动生成倒排索引或其他适合的数据结构(如 BKD tree 用于数值和日期类型)来加速查询和排序操作。索引机制使得 Elasticsearch 可以高效处理各种类型的数据查询需求。

elasticsearch 会对int, data, keyword, boolean等字段创建索引,是默认行为吗,需要加额外配置吗

Elasticsearch 默认会对 int(数值类型)、date(日期类型)、keyword(关键字类型)、boolean(布尔类型)等字段创建索引,无需额外配置。这是 Elasticsearch 的默认行为,旨在提供高效的查询能力。

具体解释如下:

  1. int(数值类型)

    • 数值类型字段(如 integerlongshort 等)默认情况下会被索引,以便支持范围查询和排序。
  2. date(日期类型)

    • 日期类型字段默认情况下会被索引,用于支持日期范围查询和排序。
  3. keyword(关键字类型)

    • 关键字类型字段默认情况下会被索引,以便进行精确匹配查询、过滤和聚合。
  4. boolean(布尔类型)

    • 布尔类型字段默认情况下会被索引,用于布尔值查询。

不创建索引的情况:

如果你不希望对某些字段创建索引,可以在映射(mapping)中明确设置这些字段的 index 属性为 false。例如:

{
  "mappings": {
    "properties": {
      "field_name": {
        "type": "keyword",
        "index": false
      }
    }
  }
}

这种配置告诉 Elasticsearch 不对 field_name 字段创建索引,但字段的原始数据仍然会存储在 _source 中。

额外配置的情况:

默认的索引行为适用于大多数场景,但如果有特定需求(如自定义分析器、禁用索引、定义字段格式等),则需要在映射中进行额外配置。

已创建的文档,字段类型不能更改是吗

是的,在 Elasticsearch 中,一旦文档的字段类型在索引中被定义并使用,就无法直接修改字段类型。这是因为字段类型影响到数据的存储方式和索引方式,如果修改字段类型,可能导致现有数据与新定义的字段类型不兼容。

解决方法:

如果需要修改字段类型,可以考虑以下几种方案:

  1. 创建新索引

    • 创建一个新索引,并在新的映射(mapping)中定义所需的字段类型。
    • 将旧索引的数据重新索引到新索引中。
    • 完成后,将应用程序切换到新索引。
  2. 使用动态模板(Dynamic Templates)

    • 如果你在动态映射时发现字段类型被错误定义,可以使用动态模板来细化字段类型的自动推断逻辑。
  3. 通过脚本重新索引

    • 使用 _reindex API,通过脚本对数据进行转换,将数据从旧索引迁移到新索引,同时应用新的字段类型。
  4. 创建多字段(Multi-fields)

    • 如果希望对同一字段以多种不同的方式进行索引,可以使用多字段的机制,而不需要更改现有的字段类型。例如,一个字段可以同时被索引为 textkeyword 类型。
{
  "mappings": {
    "properties": {
      "field_name": {
        "type": "text",
        "fields": {
          "raw": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

注意事项:

  • 修改字段类型可能会影响查询性能和存储效率,因此在做出这些更改之前,最好仔细规划和测试。
  • 如果有大量的数据,重新索引的过程可能需要一定时间,可能需要计划在低流量时间段进行。

Elasticsearch对分页查询的支持

Elasticsearch 提供了几种方式来实现分页查询。以下是常用的分页方法:

1. 基于 fromsize 的分页

这是 Elasticsearch 最基本的分页方式,类似于 SQL 中的 LIMITOFFSET

  • 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 特性来分割请求。

  1. 初始化查询:

    • 首先,定义查询参数,包括排序字段、slice.shard_sizeslice.idslice.total
    • 示例命令如下:
      GET /example_index/_search
      {
        "size": 0,  // 不返回文档,仅用于获取总数
        "query": {
          "match_all": {}
        }
      }
      

    这个查询用于获取索引中总共有多少文档。

  2. 计算分片数量:

    • 假设你想要每页返回 10 条文档,并且知道索引中共有多少文档,你可以计算出需要多少个分片请求。
    • 例如,如果有 1000 条文档,每页返回 10 条,则总共需要 100 个分片请求。
  3. 执行分片查询:

    • 对于每个分片请求,你需要指定 slice.shard_sizeslice.idslice.total
    • 示例命令如下:
      GET /example_index/_search
      {
        "slice": {
          "shard_size": 10,  // 每个分片返回的文档数量
          "id": 0,           // 当前分片的 ID
          "total": 100       // 总共分片的数量
        },
        "sort": ["_doc"],  // 排序字段
        "query": {
          "match_all": {}
        }
      }
      

    这个命令会返回第一个分片的 10 条文档。

  4. 合并结果:

    • 你需要将所有分片请求的结果合并起来,以得到完整的分页结果。

注意事项

  • 并发执行:
    • slice 特性支持并发执行多个分片请求,这意味着你可以在客户端并行发起这些请求,以提高查询效率。
  • 结果合并:
    • 你需要在客户端合并所有分片请求的结果,以获得最终的分页结果。
  • 排序字段:
    • 确保所有分片请求使用相同的排序字段,以确保分页的一致性。
  • 分片大小:
    • slice.shard_size 应该与每页返回的文档数量相匹配。

总结

  • slice 特性允许你将大的搜索请求分割成多个较小的请求,并将这些请求并行执行。
  • 通过合理设置 slice.shard_sizeslice.idslice.total,可以有效地实现分页查询。
  • 最终结果需要在客户端合并所有分片请求的结果。

希望这些信息对你有所帮助!如果有更具体的问题或需要进一步的帮助,请随时提问。

总结

  • fromsize:适用于小规模数据集的简单分页。
  • 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(或其他数值类型,如 longfloatdouble 等)进行相等比较,可以使用 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"
    }
  }
}

功能与特点

  1. 分词查询

    • match 查询会根据字段的分析器(Analyzer)对查询字符串进行分词,然后在索引中查找分词后的词条。
    • 例如,针对 "quick brown fox" 这样的查询字符串,Elasticsearch 可能会将其分词为 ["quick", "brown", "fox"],然后查询这三个词条。
  2. 操作符

    • 默认情况下,match 查询会使用 OR 操作符,即只要分词后的一个词条匹配,文档就会被返回。
    • 可以通过设置 operator 参数来控制匹配行为:
      • "or"(默认):任意一个词条匹配即返回文档。
      • "and":所有词条都必须匹配才返回文档。
{
  "query": {
    "match": {
      "field_name": {
        "query": "quick brown fox",
        "operator": "and"
      }
    }
  }
}
  1. 匹配模式
    • match_phrase:用于匹配一个完整的短语,而不是分词后的独立词条。
    • match_phrase_prefix:匹配以特定短语开头的字段值。
{
  "query": {
    "match_phrase": {
      "field_name": "quick brown fox"
    }
  }
}
  1. 模糊匹配
    • 可以通过设置 fuzziness 参数来实现模糊匹配,允许少量的拼写错误或字符替换。
{
  "query": {
    "match": {
      "field_name": {
        "query": "quikc",
        "fuzziness": "AUTO"
      }
    }
  }
}
  1. 零次或更多次出现
    • 通过 minimum_should_match 参数,你可以指定必须匹配的最少词条数量。
{
  "query": {
    "match": {
      "field_name": {
        "query": "quick brown fox",
        "minimum_should_match": 2
      }
    }
  }
}
  1. Boost(权重)
    • 你可以使用 boost 参数提高某些查询条件的权重,使其在评分时更具影响力。
{
  "query": {
    "match": {
      "field_name": {
        "query": "quick brown fox",
        "boost": 2.0
      }
    }
  }
}

适用场景

  • match 查询适合进行全文搜索,当你需要在一个文本字段中查找包含某些关键词的文档时,非常适合使用。
  • 如果你希望进行精确匹配(如查找特定的标识符、标签等),term 查询可能更合适。

match 查询是 Elasticsearch 中处理自然语言和文本搜索的核心工具之一,能够在大规模文本数据中快速找到相关内容。

match_phrase:用于匹配一个完整的短语,而不是分词后的独立词条。于term的区别

match_phraseterm 都是 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): 按从大到小的顺序排序。
示例:排序的基本用法

假设我们有一个字段 pricedate,我们希望首先按 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"
    }
  }
}
Logo

一起探索未来云端世界的核心,云原生技术专区带您领略创新、高效和可扩展的云计算解决方案,引领您在数字化时代的成功之路。

更多推荐