珠海哪里学网站开发,360未经证实的网站如何做,最新的域名,网站开发合同付款比例一、索引操作
#xff08;一#xff09;创建索引
创建Elasticsearch#xff08;ES#xff09;索引是在ES中存储和管理数据的重要操作之一。索引是用于组织和检索文档的结构化数据存储。
当创建Elasticsearch索引时#xff0c;通常需要同时指定索引的设置#xff08;Se…
一、索引操作
一创建索引
创建ElasticsearchES索引是在ES中存储和管理数据的重要操作之一。索引是用于组织和检索文档的结构化数据存储。
当创建Elasticsearch索引时通常需要同时指定索引的设置Settings和映射Mappings。以下是一个包括索引的设置和映射的示例
PUT /my_index
{settings: {number_of_shards: 5,number_of_replicas: 1},mappings: {properties: {field1: {type: text,analyzer: standard},field2: {type: keyword},field3: {type: integer},field4: {type: date,format: yyyy-MM-dd}}}
}在这个示例中 settings 部分包括索引的配置设置。例如它指定了索引将被分成5个主分片number_of_shards并包含1个副本number_of_replicas。您可以根据需求自定义这些设置。 mappings 部分用于定义索引中的字段映射。每个字段都包括字段名、数据类型例如text、keyword、integer、date等以及可选的属性例如分析器、日期格式等。
这个示例通过DSL告诉Elasticsearch如何创建索引、如何配置索引的主分片和副本以及如何映射字段以便正确存储和检索文档数据。在创建索引后可以将文档添加到索引中并使用查询DSL执行各种查询操作。
假设您正在构建一个电子商务网站需要存储和检索产品信息。可以定义产品索引的映射包括产品名称、描述、价格等字段的数据类型和属性。
DSL示例
PUT /products
{mappings: {properties: {product_name: {type: text,analyzer: standard},description: {type: text,analyzer: english},price: {type: float},category: {type: keyword}}}
}Java示例
CreateIndexRequest request new CreateIndexRequest(products);
request.mapping(_doc, product_name, typetext,analyzerstandard,description, typetext,analyzerenglish,price, typefloat,category, typekeyword
);CreateIndexResponse createIndexResponse client.indices()
.create(request, RequestOptions.DEFAULT);二删除索引
删除 ElasticsearchES索引是一项重要的操作可以用来清理不再需要的数据索引。要删除 Elasticsearch 索引可以使用以下常规DSL语句
DELETE /my_index在上述示例中DELETE 是 HTTP 请求方法/my_index 是要删除的索引名称。这个简单的DSL语句会告诉 Elasticsearch 删除名为 my_index 的索引及其所有数据。 DELETE这是 HTTP 请求方法指示 Elasticsearch 执行删除操作。 /my_index这是要删除的索引的名称。确保您提供的索引名称是正确的因为删除后无法恢复。
假设您运营一个博客平台以索引和存储博客文章。有时您可能需要删除某些旧的博客索引以释放存储空间。要删除名为 blog_posts 的博客索引可以使用以下DSL语句
DELETE /blog_posts对应java代码可以为
DeleteIndexRequest deleteRequest new DeleteIndexRequest(blog_posts);
AcknowledgedResponse deleteResponse client.indices()
.delete(deleteRequest, RequestOptions.DEFAULT);if (deleteResponse.isAcknowledged()) {System.out.println(博客索引删除成功);
} else {System.out.println(博客索引删除失败);
}三关闭索引
关闭 ElasticsearchES索引是一种操作可以将索引设置为不可用状态以减少资源消耗但仍然保留索引定义和数据。要关闭 Elasticsearch 索引可以使用以下常规DSL语句
POST /my_index/_close在上述示例中POST 是 HTTP 请求方法/my_index/_close 是要关闭的索引的路径。这个DSL语句会告诉 Elasticsearch 关闭名为 my_index 的索引。 POST这是 HTTP 请求方法用于执行关闭操作。 /my_index/_close这是要关闭的索引的路径。请注意关闭操作是通过向索引的特殊路径发送 POST 请求来执行的。
假设您运营一个文档管理系统使用 Elasticsearch 来存储文档索引。有时您可能需要关闭某个索引以释放资源但仍然保留索引定义以便以后再次启用。要关闭名为 document_index 的文档索引可以使用以下DSL语句
POST /document_index/_close对应java代码可写为
CloseIndexRequest closeIndexRequest new CloseIndexRequest(document_index);
AcknowledgeResponse closeResponse client.indices()
.close(closeIndexRequest, RequestOptions.DEFAULT);if (closeResponse.isAcknowledged()) {System.out.println(索引关闭成功);
} else {System.out.println(索引关闭失败);
}四打开索引
打开 ElasticsearchES索引是一种操作可以将先前关闭的索引重新设置为可用状态以便进行搜索和写入操作。要打开 Elasticsearch 索引可以使用以下常规DSL语句
POST /my_index/_open在上述示例中POST 是 HTTP 请求方法/my_index/_open 是要打开的索引的路径。这个DSL语句会告诉 Elasticsearch 打开名为 my_index 的索引。 POST这是 HTTP 请求方法用于执行打开操作。 /my_index/_open这是要打开的索引的路径。请注意打开操作是通过向索引的特殊路径发送 POST 请求来执行的。
假设您运营一个文档管理系统使用 Elasticsearch 存储文档索引。有时可能需要重新打开以前关闭的索引以便用户可以再次访问和搜索文档。要重新打开名为 document_index 的文档索引可以使用以下DSL语句
POST /document_index/_open对应java代码可写为
OpenIndexRequest openIndexRequest new OpenIndexRequest(document_index);
OpenIndexResponse openResponse client.indices()
.open(openIndexRequest, RequestOptions.DEFAULT);if (openResponse.isAcknowledged()) {System.out.println(索引打开成功);
} else {System.out.println(索引打开失败);
}这个示例适用于文档管理系统如果先前关闭的文档索引需要再次被用户访问和搜索那么重新打开索引是一个有效的操作。这可以用于重新激活不再频繁使用但仍然有价值的索引。
总之重新打开 Elasticsearch 索引是一种管理索引可用性的操作可用于恢复先前关闭的索引以进行搜索和写入操作。根据具体需求可以使用DSL或 Elasticsearch 客户端库来执行此操作。请注意重新打开索引后用户可以再次对其执行搜索和写入操作。
五索引别名
Elasticsearch索引别名是一项强大的功能用于管理索引的命名别称以提供更灵活的索引管理和查询。
用法分析 索引版本控制索引别名可以用于实现索引版本控制。当您需要更新索引时可以创建一个新的索引并将别名指向新索引而不需要更改应用程序中的查询。这使得您可以平滑地进行索引维护和升级。 切换索引别名允许您在不中断查询的情况下切换索引。这对于在索引上执行滚动更新、备份、恢复和数据迁移等操作时非常有用。 多索引查询您可以将一个别名关联到多个索引上从而实现多索引查询。这对于执行跨多个索引的复杂查询非常有用而无需明确指定每个索引的名称。 索引分割与归档索引别名可以用于将数据分割到不同的索引中以便更好地管理大量数据。例如您可以创建每天一个新索引然后使用别名汇总它们之后可以轻松地归档或删除旧的索引。 索引安全性通过使用别名您可以在后端更改实际索引名称从而增强索引的安全性。外部用户不需要知道真正的索引名称。
注意事项 别名不是索引索引别名本身不存储数据它只是一个指向一个或多个索引的符号引用。因此创建和删除别名是低成本的操作。 别名更改是原子操作将别名切换到新索引或删除别名是原子操作这意味着它们不会中断正在执行的查询。但请注意将别名从一个索引切换到另一个索引后新的索引可能需要时间来完全加载数据。 谨慎使用别名虽然索引别名非常强大但也需要谨慎使用。不恰当的别名管理可能会导致混淆和错误。 版本控制的注意事项当使用别名进行索引版本控制时需要确保新索引的映射与旧索引的映射兼容。否则应用程序可能会出现问题。 查询性能尽管别名可以提高查询的灵活性但跨多个索引执行查询可能会增加性能开销。请谨慎设计查询以优化性能。
总之索引别名是 Elasticsearch 灵活索引管理的有力工具但需要仔细规划和使用。它们可以用于索引版本控制、查询优化和索引维护但需要谨慎管理以确保正确性和性能。
应用案例举例和具体案例展示
案例举例-版本控制
案例假设您的应用程序存储用户生成的文档并且您需要定期更新文档结构例如添加新字段或更改映射。同时您希望用户可以持续访问其旧文档并逐渐迁移到新文档结构。解决方案您可以为每个文档类型创建一个别名例如v1和v2每个别名指向不同版本的索引。当您需要更新索引时创建一个新的索引版本并将别名指向新索引。这样新文档将被写入新索引而用户仍然可以查询旧索引以访问旧文档。逐渐迁移用户到新索引后您可以删除旧索引。
案例举例-多索引查询
案例您的应用程序需要执行复杂的查询涉及多个索引。例如在电子商务平台上您可能有一个索引用于存储产品信息另一个用于存储订单信息而查询需要同时涵盖这两个索引。解决方案创建一个别名例如ecommerce_data将其指向产品和订单索引。然后您的查询可以针对ecommerce_data别名执行而无需明确指定每个索引的名称。这使得查询更简单且更具可维护性。
案例举例-索引分割与归档
案例您的应用程序需要存储大量数据例如日志数据但不希望将所有数据存储在一个巨大的索引中。您还希望能够轻松地归档旧数据同时保持查询的可用性。解决方案创建一个别名例如logs将其指向每天一个新索引。每天结束时创建新索引并更新别名这样新数据将被写入新索引。旧索引可以被归档或删除而查询可以继续使用logs别名无需更改。
案例举例索引切换
案例您的应用程序需要进行滚动更新例如将新版本的数据引入到生产环境中同时确保零停机时间。解决方案创建一个别名例如live_data将其指向当前的生产索引。然后将新索引准备好并在准备就绪后将别名从旧索引切换到新索引。这样新数据将在不中断查询的情况下引入到生产环境中。
这些案例说明了索引别名在处理数据版本控制、查询优化、数据分割与归档以及索引切换方面的实际应用。通过巧妙使用别名可以更灵活地管理和操作您的 Elasticsearch 索引同时确保数据的可用性和性能。
选择上面提到的 版本控制 案例并进行具体的展示和分析步骤。这个案例涉及使用索引别名进行索引版本控制允许平滑地更新索引结构而不中断用户查询。
背景假设我们运营一个博客平台使用 Elasticsearch 来存储博客文章。需要定期更新博客文章的结构例如添加新字段或更改映射。同时希望用户可以持续访问其旧的博客文章并逐渐迁移到新的文章结构。
第一步创建初始索引和别名
创建初始的博客索引例如 blog_posts_v1。
PUT /blog_posts_v1
{mappings: {properties: {title: {type: text},content: {type: text},date_published: {type: date}}}
}创建一个别名 blog_posts将其指向初始的博客索引。
POST /_aliases
{actions: [{add: {index: blog_posts_v1,alias: blog_posts}}]
}第二步定期更新索引结构。当需要更新索引结构时创建一个新的博客索引例如 blog_posts_v2并更新映射。
PUT /blog_posts_v2
{mappings: {properties: {title: {type: text},content: {type: text},date_published: {type: date},author: {type: keyword}}}
}第三步切换别名。一旦新的博客索引 blog_posts_v2 准备就绪使用别名切换将别名 blog_posts 从旧索引 blog_posts_v1 切换到新索引 blog_posts_v2。
POST /_aliases
{actions: [{remove: {index: blog_posts_v1,alias: blog_posts}},{add: {index: blog_posts_v2,alias: blog_posts}}]
}第四步用户迁移。用户可以继续访问和查询博客文章而无需更改他们的查询代码。新的博客文章将写入新的索引 blog_posts_v2而旧的博客文章仍然可查询。
第五步清理旧索引。定期清理旧的博客索引例如blog_posts_v1或者在不再需要它们时进行归档或删除。
这个案例说明了如何使用索引别名在更新索引结构时平滑地迁移用户到新的索引版本同时保持查询的连续性。索引别名是实现版本控制和索引维护的有力工具。
二、映射操作
在 Elasticsearch 中映射Mapping是用来定义如何存储和索引文档中字段的方式的重要概念。映射操作用于指定字段的数据类型、分析器以及其他属性以便 Elasticsearch 能够正确地处理和查询文档中的数据。
映射是 Elasticsearch 中的元数据它描述了索引中每个字段的数据类型、如何被索引以及如何存储。它允许 Elasticsearch 理解和处理文档中的数据。
映射的主要元素
数据类型定义字段的数据类型如文本、数字、日期、地理位置等。分析器Analyzer指定用于分词和处理文本字段的分析器。分析器将文本字段拆分成单词以便进行全文搜索。属性Properties定义字段的其他属性如是否可搜索、是否存储原始值、是否支持排序等。嵌套映射Nested Mapping用于处理复杂数据结构如嵌套文档或数组。
映射对于正确索引和查询文档非常重要。如果映射不正确将导致搜索和分析错误。正确的映射可以优化查询性能使 Elasticsearch 能够更好地理解和处理文档数据。一旦索引创建后通常不能直接更改映射。但可以通过重新索引数据或创建新索引来应用新的映射。
映射的注意事项
映射的设计需要仔细考虑因为不正确的映射可能会导致数据不一致或搜索性能下降。映射更改可能需要谨慎处理特别是在生产环境中因为不正确的映射更改可能会导致数据丢失或不可用。
总之映射是 Elasticsearch 中用于定义和管理索引字段的关键操作。正确的映射设计可以提高查询性能和数据质量而不正确的映射可能会导致问题。在设计和管理索引时请谨慎考虑映射的使用和更改。
一查看映射
在 Elasticsearch 中可以使用映射操作查看索引的映射信息。要查看索引的映射可以使用以下常规DSL语句
GET /my_index/_mapping
在上述示例中GET 是 HTTP 请求方法/my_index/_mapping 是要查看映射的索引名称。 GET这是 HTTP 请求方法用于执行查看映射操作。 /my_index/_mapping这是要查看映射的索引的路径。
假设运营一个电子商务网站使用 Elasticsearch 来存储产品信息。电子商务网站存储产品信息的 Elasticsearch 索引名为 products该索引包含产品的名称、价格、描述等信息。使用以下DSL语句来查看产品索引 products 的映射
GET /products/_mapping
使用以下DSL请求 GET /products/_mapping 会返回关于索引 products 的映射信息。返回结果将是一个JSON格式的响应其中包含有关索引中字段的详细信息。以下是对返回结果的分析说明
{products: {mappings: {properties: {name: {type: text,fields: {keyword: {type: keyword,ignore_above: 256}}},price: {type: float},description: {type: text},// 其他字段...}}}
}二扩展映射
在 Elasticsearch 中扩展映射Mapping Expansion是一项操作用于在已有的索引映射基础上添加新的字段或修改已有字段的属性。这可以用于动态地适应数据模型的变化或为索引中的字段添加新功能。以下是有关扩展映射的分析
扩展映射的使用场景 适应数据模型的变化当应用程序需要存储新类型的数据或更改现有数据的结构时扩展映射是一种灵活的方式。例如可以将新的文本字段添加到索引以存储新类型的信息。 引入新的数据属性可能需要在索引中添加新的字段来存储与现有数据相关的新属性。例如如果索引包含产品信息可能希望在以后添加字段来存储产品的新特性。 索引迭代和升级当需要对索引进行迭代和升级时扩展映射是必要的。例如如果在旧版本的索引中不包括某些字段但在新版本中需要这些字段可以扩展映射以包括这些字段。
扩展映射的操作步骤 创建新映射首先需要定义新字段的映射。这包括指定字段的数据类型、分析器和其他属性。可以通过创建一个新的索引映射来完成。 将新映射添加到索引一旦新映射定义好了可以使用索引别名或新的索引名称将新映射添加到索引中。 重新索引数据如果新映射需要应用于已有的数据需要重新索引现有数据以适应新的映射。这可以通过重新索引工具或 Elasticsearch 的 Reindex API 来实现。 测试和验证在应用新映射之前建议对其进行测试和验证以确保数据存储和查询操作按预期工作。
注意事项和考虑因素 扩展映射可能需要一些索引维护工作特别是对于大型索引。重新索引数据可能会导致一些性能开销。 在扩展映射时确保新映射的定义与应用程序的需求和数据模型一致。 考虑数据迁移策略特别是在高可用性和生产环境中。数据迁移应谨慎进行以确保不会导致数据丢失或中断查询。
总之扩展映射是 Elasticsearch 中用于适应数据模型变化和引入新属性的重要操作。它提供了灵活性允许根据应用程序需求不断发展和扩展索引映射。在执行扩展映射操作时请谨慎规划和测试以确保数据的完整性和性能。
业务举例扩展映射以添加作者和标签字段
假设运营一个在线新闻门户网站使用 Elasticsearch 来存储新闻文章的索引。最初的索引只包含文章的标题、内容和发布日期。现在我们决定扩展映射以添加新的字段以存储文章的作者和标签。新闻门户网站使用 Elasticsearch 索引 news_articles 来存储新闻文章。最初的映射定义如下
{news_articles: {mappings: {properties: {title: {type: text},content: {type: text},publish_date: {type: date}}}}
}现在决定扩展映射以包括文章的作者和标签信息。
第一步创建新映射。需要创建新的映射以包括作者和标签字段。新映射如下所示
{news_articles: {mappings: {properties: {title: {type: text},content: {type: text},publish_date: {type: date},author: {type: text},tags: {type: keyword}}}}
}在新映射中我们添加了两个新字段author 和 tags分别用于存储文章的作者名字和标签以关键字类型存储。
第二步将新映射添加到索引。为了将新映射添加到现有索引中可以执行以下步骤
创建一个新的索引例如 news_articles_v2并应用新的映射。使用 Elasticsearch 的 Reindex API 将现有索引中的数据重新索引到新索引中。在此过程中新映射将被应用于已有的数据。更新索引别名以使别名指向新的索引使其成为主要的查询目标。
第三步测试和验证。在应用新映射之前进行测试和验证以确保查询和索引操作按预期工作。确保新字段的数据存储和检索都正确无误。
三基本的数据类型
keyword类型
在 Elasticsearch 映射操作中keyword 类型是一种常用的基本数据类型用于存储关键字数据。与 text 类型不同keyword 类型不进行分词它将整个文本视为单个词条。这使得 keyword 类型非常适合用于排序、聚合和精确匹配等操作。 关键字数据keyword 类型用于存储不需要分词的关键字数据。这包括标签、标识符、名称、状态等文本信息通常需要进行精确匹配或按照字母顺序排序。 不分词与 text 类型不同keyword 类型不会对文本进行分词。它将整个文本视为单个词条保留原始文本的完整性。 精确匹配和排序由于不进行分词keyword 类型非常适合进行精确匹配例如过滤和筛选操作和排序操作。您可以确保查询的精确匹配而不受分词的影响同时还可以按照字母顺序对数据进行排序。 不适用于全文搜索由于不进行分词keyword 类型不适用于全文搜索。如果需要全文搜索通常应使用 text 类型。
假设您正在使用 Elasticsearch 存储产品信息并且每个产品都有一个标签列表希望能够按照标签进行精确匹配和排序。
创建一个索引映射包括一个 keyword 类型的字段来存储产品标签。
PUT /products
{mappings: {properties: {name: {type: text},tags: {type: keyword}}}
}向索引中添加一些产品文档包括标签信息。
POST /products/_doc/1
{name: Product A,tags: [electronics, smartphone]
}POST /products/_doc/2
{name: Product B,tags: [clothing, shoes]
}执行一个精确匹配的查询查找包含特定标签的产品。
GET /products/_search
{query: {match: {tags: electronics}}
}此查询将返回包含 electronics 标签的产品而不会返回包含 smartphone 标签的产品。
执行一个排序查询按标签字段的字母顺序对产品进行排序。
GET /products/_search
{sort: [{tags: asc}]
}此查询将返回产品按标签字段的字母顺序升序排列。
通过使用 keyword 类型来存储标签信息可以轻松地进行精确匹配和排序同时保留了标签的原始完整性。这在许多应用中非常有用特别是在需要处理结构化数据的情况下。
text类型
在 Elasticsearch 映射操作中text 类型是一种常用的基本数据类型用于存储文本数据通常用于全文搜索和分析。 文本数据text 类型主要用于存储文本数据例如文章内容、产品描述、评论等。这些字段通常需要进行全文搜索和分析。 分词text 类型会对文本进行分词将文本拆分成单词或词条以便更好地支持全文搜索和分析。分词可以根据配置的分析器进行以便处理不同语言和文本特性。 全文搜索由于分词的支持text 类型非常适合进行全文搜索操作。它允许用户查询包含特定单词或短语的文档而不需要精确匹配整个字段内容。 分析功能text 类型还支持分析功能包括在搜索时执行文本预处理如小写化、去停用词、词干提取等以及相关性评分。
假设正在使用 Elasticsearch 存储产品评论希望能够搜索和分析评论内容。创建一个索引映射包括一个 text 类型的字段来存储评论内容。
PUT /product_reviews
{mappings: {properties: {product_name: {type: keyword},comment: {type: text}}}
}向索引中添加一些产品评论文档。
POST /product_reviews/_doc/1
{product_name: Product A,comment: This product is amazing! I love it.
}POST /product_reviews/_doc/2
{product_name: Product B,comment: Not satisfied with this product. It doesnt meet my expectations.
}执行一个全文搜索的查询查找包含特定关键字的评论。
GET /product_reviews/_search
{query: {match: {comment: amazing}}
}此查询将返回包含 amazing 关键字的评论。
执行一个分析查询使用分析功能评分。
GET /product_reviews/_search
{query: {match_phrase: {comment: product satisfaction}},sort: [_score // 根据相关性评分排序]
}
此查询将返回包含 product satisfaction 短语的评论并且可以根据相关性进行排序。
{took: 15,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 2,relation: eq},max_score: 1.2345678, // 最高评分hits: [{_index: product_reviews,_type: _doc,_id: 3,_score: 1.2345678, // 文档的评分_source: {product_name: Product C,comment: I have found great product satisfaction with this item.}},{_index: product_reviews,_type: _doc,_id: 4,_score: 0.9876543, // 文档的评分_source: {product_name: Product D,comment: Product satisfaction is important for me.}}]}
}通过使用 text 类型来存储评论内容可以进行全文搜索和分析以更好地理解用户的反馈和需求。这对于处理文本数据的应用场景非常有用例如产品评论、新闻文章、博客内容等。
数值类型
在 Elasticsearch 映射操作中数值类型用于存储数值数据这些数据通常包括整数和浮点数。数值类型非常适用于执行范围查询、聚合操作和数值计算。主要数值类型如下 integer用于存储整数值。适用于存储没有小数部分的整数。 long用于存储长整数值。通常用于存储较大范围的整数。 float用于存储单精度浮点数值。 double用于存储双精度浮点数值。通常用于存储高精度的浮点数。
这些数值类型用于存储不同范围和精度的数值数据以支持各种数值计算和分析需求。
假设正在使用 Elasticsearch 存储销售数据其中包括产品的价格浮点数和销售数量整数。创建一个名为 sales 的索引其中包括了价格price和销售数量quantity字段
PUT /sales
{mappings: {properties: {price: {type: float},quantity: {type: integer}}}
}插入了两个产品的销售数据
POST /sales/_doc/1
{price: 75.99,quantity: 15
}POST /sales/_doc/2
{price: 95.50,quantity: 20
}假设希望查找价格在 50 到 100 之间且销售数量大于等于 10 的产品。
GET /sales/_search
{query: {bool: {must: [{range: {price: {gte: 50,lte: 100}}},{range: {quantity: {gte: 10}}}]}}
}返回结果将包含与查询条件匹配的文档。
{took: 10,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 2,relation: eq},max_score: 1.0,hits: [{_index: sales,_type: _doc,_id: 1,_score: 1.0,_source: {product_name: Product A,price: 75.99,quantity: 15}},{_index: sales,_type: _doc,_id: 2,_score: 1.0,_source: {product_name: Product B,price: 95.50,quantity: 20}}]}
}分析说明 查询使用了 range 查询来查找价格在 50 到 100 之间的产品以及销售数量大于等于 10 的产品。 返回结果包含了匹配的文档每个文档都包括了相关信息和相关性评分。 查询结果中包括两个产品它们的价格和销售数量满足查询条件。
这个示例演示了如何使用数值类型进行范围查询以查找满足特定条件的文档。数值类型非常适用于存储和查询数值数据对于分析、统计和报告等用途非常有用。
布尔类型
在 Elasticsearch 映射操作中布尔类型Boolean是一种基本的数据类型用于存储布尔值即 true 或 false。布尔类型通常用于存储表示真假条件的信息例如是否已完成、是否可用等。 布尔数据布尔类型用于存储布尔值它们表示真假条件。在 Elasticsearch 中布尔字段可以用于标识文档是否满足某些条件。 存储效率布尔字段非常节省存储空间因为它们只需要一个位来表示 true 或 false。这对于存储大量布尔信息的索引非常有用。 查询和过滤布尔字段可用于执行查询和过滤操作。可以根据布尔字段的值来筛选文档例如查找所有已完成的任务或所有可用的产品。
假设正在使用 Elasticsearch 存储任务列表并希望标识哪些任务已完成true和哪些任务未完成false。使用 PUT 请求创建一个索引index并指定索引映射mapping。在此示例中我们创建一个名为 tasks 的索引并定义了两个字段任务名称task_name和是否已完成is_completed。
PUT /tasks
{mappings: {properties: {task_name: {type: text},is_completed: {type: boolean}}}
}插入一些示例任务数据的请求
POST /tasks/_doc/1
{task_name: Task A,is_completed: true
}POST /tasks/_doc/2
{task_name: Task B,is_completed: false
}POST /tasks/_doc/3
{task_name: Task C,is_completed: true
}假设要查询所有已完成的任务
GET /tasks/_search
{query: {term: {is_completed: true}}
}返回结果将包含已完成的任务文档
{took: 5,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 3,relation: eq},max_score: 1.0,hits: [{_index: tasks,_type: _doc,_id: 1,_score: 1.0,_source: {task_name: Task A,is_completed: true}},{_index: tasks,_type: _doc,_id: 3,_score: 1.0,_source: {task_name: Task C,is_completed: true}}]}
}查询使用了 term 查询来查找 is_completed 字段为 true 的任务。 返回结果包含了已完成的任务文档每个文档都包括了相关信息和相关性评分如果使用相关性评分。
这个示例演示了如何使用布尔类型字段来标识和查询已完成的任务。布尔类型在存储和查询表示真假条件的信息时非常有用例如任务状态、商品可用性等。通过这种方式可以有效地管理和查询布尔值数据。
日期类型
在 Elasticsearch 映射操作中日期类型Date是一种基本的数据类型用于存储日期和时间信息。日期类型通常用于记录事件发生的时间戳或日期值。 日期时间数据日期类型用于存储日期和时间信息通常表示为 ISO 8601 格式的日期字符串例如2023-10-06T15:30:00Z。 存储格式Elasticsearch 内部将日期类型存储为 UNIX 时间戳以毫秒为单位但可以在查询和返回结果中使用更人类可读的日期字符串。 支持的日期格式Elasticsearch 支持多种日期格式的解析允许索引不同格式的日期并在查询时执行日期范围过滤和聚合。 时区处理日期类型支持时区信息以确保正确处理不同时区的日期和时间。
假设您正在使用 Elasticsearch 存储新闻文章并希望记录每篇文章的发布日期。使用 PUT 请求创建一个索引index并指定索引映射mapping。在此示例中我们创建一个名为 news_articles 的索引并定义了两个字段新闻标题headline和发布日期publish_date。
PUT /news_articles
{mappings: {properties: {headline: {type: text},publish_date: {type: date}}}
}插入一些示例新闻文章数据的请求
POST /news_articles/_doc/1
{headline: Elasticsearch 8.0 Released,publish_date: 2023-04-15T10:30:00Z
}POST /news_articles/_doc/2
{headline: Big Data Summit 2023 Recap,publish_date: 2023-07-20T14:45:00Z
}POST /news_articles/_doc/3
{headline: AI Advances in Healthcare,publish_date: 2023-11-10T08:15:00Z
}假设您要查询所有发布日期在特定时间段内的文章
GET /news_articles/_search
{query: {range: {publish_date: {gte: 2023-01-01T00:00:00Z,lte: 2023-12-31T23:59:59Z}}}
}返回结果将包含发布日期在指定时间段内的文章
{took: 5,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 3,relation: eq},max_score: 1.0,hits: [{_index: news_articles,_type: _doc,_id: 1,_score: 1.0,_source: {headline: Article A,publish_date: 2023-04-15T10:30:00Z}},{_index: news_articles,_type: _doc,_id: 2,_score: 1.0,_source: {headline: Article B,publish_date: 2023-07-20T14:45:00Z}},{_index: news_articles,_type: _doc,_id: 3,_score: 1.0,_source: {headline: Article C,publish_date: 2023-11-10T08:15:00Z}}]}
}查询使用了 range 查询来查找发布日期在 2023 年内的文章。 返回结果包含了发布日期在指定时间段内的文章每个文档都包括了相关信息和相关性评分如果使用相关性评分。
这个示例演示了如何使用日期类型字段来存储和查询日期信息。日期类型在存储和分析与时间相关的数据时非常有用例如新闻发布日期、事件发生时间等。通过这种方式可以轻松地执行日期范围过滤和聚合操作以满足各种时间相关的查询需求。
四复杂数据类型
数组类型
在 Elasticsearch 映射操作中数组类型用于存储多个值的集合这些值可以是相同类型的也可以是不同类型的。数组类型通常用于表示复杂的多值字段例如标签、评论、作者列表等。 数组数据数组类型允许在单个字段中存储多个值这些值可以是文本、数字、日期或其他数据类型。 多值字段与传统数据库不同Elasticsearch 允许字段具有多个值而不需要创建多个字段。这使得数组类型非常适用于存储多值属性。 支持的数据类型数组可以包含不同类型的数据例如文本、数字、日期等。这使得它非常灵活。 查询和过滤可以使用数组字段执行查询和过滤操作例如查找包含特定值的文档或在数组中查找范围内的值。
假设您正在使用 Elasticsearch 存储图书信息每本书可以有多个作者。使用 PUT 请求创建一个索引index并指定索引映射mapping。在此示例中我们创建一个名为 books 的索引并定义了两个字段书名title和作者列表authors。
PUT /books
{mappings: {properties: {title: {type: text},authors: {type: keyword}}}
}插入一些示例图书数据的请求
POST /books/_doc/1
{title: Book A,authors: [John Smith, Alice Johnson]
}POST /books/_doc/2
{title: Book B,authors: [John Smith, David Williams]
}POST /books/_doc/3
{title: Book C,authors: [Alice Johnson, Emily Davis]
}假设要查询包含作者 John Smith 的书籍
GET /books/_search
{query: {match: {authors: John Smith}}
}返回结果将包含包含 John Smith 作为作者的书籍
{took: 7,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 2,relation: eq},max_score: 1.0,hits: [{_index: books,_type: _doc,_id: 1,_score: 1.0,_source: {title: Book A,authors: [John Smith, Alice Johnson]}},{_index: books,_type: _doc,_id: 2,_score: 1.0,_source: {title: Book B,authors: [John Smith, David Williams]}}]}
}查询使用了 match 查询来查找包含作者 John Smith 的书籍。 返回结果包含了满足查询条件的书籍文档每个文档都包括了相关信息和相关性评分如果使用相关性评分。
这个示例演示了如何使用数组类型字段来存储和查询多个值的集合。数组类型非常适用于表示多值属性例如多个作者、标签或评论。通过这种方式可以轻松地查询包含特定值的文档以满足各种多值属性的查询需求。
对象类型
在 Elasticsearch 映射操作中对象类型Object是一种复杂的数据类型用于存储嵌套的结构化数据。对象类型允许将多个字段组合到一个单独的对象中这些字段可以是不同类型的形成了文档内的嵌套结构。 对象数据对象类型用于存储嵌套的结构化数据。它允许将多个字段组织为一个单独的对象以便更好地表示数据的层次性和复杂性。 嵌套字段对象字段中的每个子字段都可以有自己的数据类型。这允许在一个文档中存储多个嵌套字段每个字段可以有不同的数据类型例如文本、数字、日期等。 结构化数据对象类型特别适用于存储具有层次结构的数据例如产品包含属性、订单包含多个项目等。 查询和过滤可以使用对象类型执行查询和过滤操作以访问和操作嵌套的数据。
假设您正在使用 Elasticsearch 存储个人信息其中每个文档表示一个人包括姓名name、地址address、联系信息contact等。
PUT /people
{mappings: {properties: {name: {type: text},address: {type: object,properties: {city: {type: text},state: {type: keyword}}},contact: {type: object,properties: {email: {type: text},phone: {type: text}}}}}
}插入一些示例数据的请求
POST /people/_doc/1
{name: Alice Johnson,address: {city: New York,state: NY},contact: {email: aliceexample.com,phone: 555-1234}
}POST /people/_doc/2
{name: Bob Smith,address: {city: Los Angeles,state: CA},contact: {email: bobexample.com,phone: 555-5678}
}假设您要查询所有居住在特定城市的人
GET /people/_search
{query: {match: {address.city: New York}}
}返回结果将包含居住在纽约的人的文档
{took: 5,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 2,relation: eq},max_score: 1.0,hits: [{_index: people,_type: _doc,_id: 1,_score: 1.0,_source: {name: Alice Johnson,address: {city: New York,state: NY},contact: {email: aliceexample.com,phone: 555-1234}}},{_index: people,_type: _doc,_id: 2,_score: 1.0,_source: {name: Bob Smith,address: {city: New York,state: NY},contact: {email: bobexample.com,phone: 555-5678}}}]}
}查询使用了 match 查询来查找居住在纽约的人。 返回结果包含了满足查询条件的人的文档每个文档都包括了姓名、地址、联系信息等嵌套字段的信息。
这个示例演示了如何使用对象类型字段来存储和查询嵌套的结构化数据。对象类型非常适用于表示层次结构的数据例如个人信息、产品属性、订单项目等。通过这种方式可以轻松地访问和操作嵌套的数据以满足各种复杂数据结构的存储和查询需求。
地理类型
在 Elasticsearch 映射操作中地理类型Geo用于存储地理位置信息如经度和纬度坐标。这种类型允许索引和查询地理位置数据以便执行空间分析和地理搜索。 地理数据地理类型用于存储地理位置信息通常表示为经度和纬度坐标。这种类型非常适用于存储地理空间数据如地点、地理区域和地理坐标。 地理索引Elasticsearch 使用地理类型来构建地理索引以便更容易地执行地理位置相关的查询和分析。这包括范围查询、距离查询、聚合等。 支持的地理形状Elasticsearch 支持多种地理形状例如点、线、多边形等使您能够索引和查询各种地理空间数据。 地理距离计算地理类型允许您计算地理坐标之间的距离以便查找在一定距离内的地理位置。
假设您正在使用 Elasticsearch 存储餐厅信息每个餐厅都有一个地理坐标希望能够查询距离特定位置一定距离范围内的餐厅。创建一个名为 restaurants 的索引其中包含了餐厅名称name和地理坐标location。
PUT /restaurants
{mappings: {properties: {name: {type: text},location: {type: geo_point}}}
}插入一些示例餐厅数据的请求
POST /restaurants/_doc/1
{name: Restaurant A,location: {lat: 40.7120,lon: -74.0050}
}POST /restaurants/_doc/2
{name: Restaurant B,location: {lat: 40.7130,lon: -74.0070}
}POST /restaurants/_doc/3
{name: Restaurant C,location: {lat: 40.7110,lon: -74.0080}
}假设要查找距离纽约市中心40.7128, -74.006010公里以内的餐厅。
GET /restaurants/_search
{query: {bool: {filter: {geo_distance: {distance: 10km,location: {lat: 40.7128,lon: -74.0060}}}}}
}返回结果将包含距离纽约市中心10公里以内的餐厅。
{took: 12,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 3,relation: eq},max_score: 1.0,hits: [{_index: restaurants,_type: _doc,_id: 1,_score: 1.0,_source: {name: Restaurant A,location: {lat: 40.7120,lon: -74.0050}}},{_index: restaurants,_type: _doc,_id: 2,_score: 1.0,_source: {name: Restaurant B,location: {lat: 40.7130,lon: -74.0070}}},{_index: restaurants,_type: _doc,_id: 3,_score: 1.0,_source: {name: Restaurant C,location: {lat: 40.7110,lon: -74.0080}}}]}
}查询使用了 geo_distance 查询来查找距离指定地理坐标一定距离范围内的餐厅。 返回结果包含了满足查询条件的餐厅文档每个文档都包括了餐厅名称和地理坐标的信息。
这个示例演示了如何使用地理类型字段来存储和查询地理位置信息。地理类型非常适用于处理地理空间数据如地点搜索、附近搜索和地理分析等需求。通过这种方式可以轻松地执行地理空间查询和分析以满足各种地理位置相关的查询需求。
五动态映射
动态映射Dynamic Mapping是 Elasticsearch 中的一项功能允许自动检测和创建索引映射无需手动定义字段的数据类型和属性。当索引文档时Elasticsearch 根据文档内容自动创建映射包括字段的数据类型、分析器、索引选项等。这使得索引的管理更加灵活特别适用于处理不断变化的数据和不确定的数据结构。
以下是常见的 JSON 数据类型和 Elasticsearch 索引类型的对应表
JSON 数据类型字符串String
Elasticsearch 索引类型text 或 keyword说明字符串类型可以映射为 text 类型用于全文搜索和分析或映射为 keyword 类型用于精确匹配和聚合。
JSON 数据类型整数Integer
Elasticsearch 索引类型integer 或 long说明整数类型可以映射为 integer 类型32 位有符号整数或 long 类型64 位有符号整数取决于数据范围。
JSON 数据类型浮点数Float/Double
Elasticsearch 索引类型float 或 double说明浮点数类型可以映射为 float 类型32 位浮点数或 double 类型64 位浮点数。
JSON 数据类型布尔值Boolean
Elasticsearch 索引类型boolean说明布尔值类型映射为 boolean 类型用于存储 true 或 false。
JSON 数据类型日期和时间Date/Time
Elasticsearch 索引类型date说明日期和时间类型映射为 date 类型用于存储日期和时间信息。
JSON 数据类型数组Array
Elasticsearch 索引类型array说明JSON 数组通常映射为 Elasticsearch 中的数组可以包含多个值。Elasticsearch 中的数组字段通常需要指定 nested 类型以支持多值字段的查询和聚合。
JSON 数据类型对象Object
Elasticsearch 索引类型object说明JSON 对象可以映射为 Elasticsearch 的对象类型用于存储嵌套的结构化数据。
JSON 数据类型地理坐标Geospatial Coordinates
Elasticsearch 索引类型geo_point说明地理坐标类型用于存储经度和纬度坐标以支持地理位置相关的查询和分析。
这个对应表展示了常见的 JSON 数据类型与 Elasticsearch 索引类型之间的映射关系。当索引文档时Elasticsearch 会根据文档的字段内容自动选择合适的数据类型。如果需要更精细的控制可以通过显式映射来定义字段的数据类型和属性。动态映射为 Elasticsearch 提供了灵活性使其适应各种数据结构和用例。
六多字段
在 Elasticsearch 中多字段Multi-Field是一种索引映射策略用于将一个字段存储在多个不同的子字段中每个子字段可以具有不同的数据类型或分析器。多字段的引入允许在一个字段上执行多种操作例如全文搜索、精确匹配、聚合等同时保留原始数据的不同表示形式。
多字段的特点和用途 数据多样性多字段允许您在一个字段上存储多个不同的数据表示以适应各种查询需求。例如一个字段可以同时存储原始文本和分析后的词汇。 支持不同数据类型每个子字段可以具有不同的数据类型。例如一个字段可以同时映射为 text 类型用于全文搜索和 keyword 类型用于精确匹配。 支持不同分析器每个子字段可以使用不同的文本分析器。这使得您可以在一个字段上执行不同类型的文本分析。 灵活性多字段使您能够针对不同的查询场景选择最合适的子字段同时保持原始数据的完整性。 支持复杂查询多字段允许您执行复杂的查询操作例如同时执行全文搜索和精确匹配或者在多个子字段上执行聚合操作。
多字段示例
假设有一个名为 product 的索引其中包含了产品名称product_name字段。希望能够在同一字段上执行全文搜索和精确匹配。以下是使用多字段的示例映射
PUT /product
{mappings: {properties: {product_name: {type: text,fields: {keyword: {type: keyword}}}}}
}在上述映射中我们定义了一个 product_name 字段并在该字段下创建了一个子字段 keyword它具有 keyword 数据类型。这个子字段将用于精确匹配。
多字段的用法示例-全文搜索要执行全文搜索可以使用原始字段 product_name。例如
GET /product/_search
{query: {match: {product_name: Elasticsearch}}
}多字段的用法示例-精确匹配要执行精确匹配可以使用子字段 product_name.keyword。例如
GET /product/_search
{query: {term: {product_name.keyword: Elasticsearch}}
}在此示例中我们分别使用原始字段和子字段执行不同类型的查询。
多字段的引入使得索引中的字段可以灵活地适应各种查询需求同时保持原始数据的完整性。这在处理多样性的数据和不同的查询场景时非常有用。
三、文档操作
一单条写入文档
在 Elasticsearch 中要进行单条写入文档操作可以使用 index 操作。要单条写入文档可以使用以下DSL语句
POST /your_index/_doc/1
{field1: value1,field2: value2,field3: 123,field4: true
}POST 请求用于创建文档。/your_index 是您的索引名称。/_doc/1 中的 1 是文档的唯一标识符您可以选择性地提供如果未提供Elasticsearch 会为您生成一个唯一标识符。JSON数据包含文档的字段和值。
分析说明 POST 请求用于创建文档。如果指定的标识符在上述示例中为 1已经存在于索引中它将更新现有文档。否则它将创建一个新的文档。 文档的字段和值在JSON数据中指定您可以根据您的业务需求提供不同的字段和数据类型。
业务举例
假设您正在构建一个电子商务平台并希望将一件商品的信息写入 Elasticsearch 中以便进行搜索和分析。以下是一个示例包括DSL和Java演示
DSL语句示例
POST /products/_doc/12345
{product_name: Laptop,description: High-performance laptop with SSD storage.,price: 999.99,in_stock: true
}Java演示
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;public class SingleDocumentIndexingExample {public static void main(String[] args) throws IOException {RestHighLevelClient client createElasticsearchClient();// 构建索引请求IndexRequest request new IndexRequest(products);request.id(12345); // 文档标识符String jsonString { \product_name\:\Laptop\, \description\:\High-performance laptop with SSD storage.\, \price\:999.99, \in_stock\:true };request.source(jsonString, XContentType.JSON);// 执行索引请求IndexResponse response client.index(request, RequestOptions.DEFAULT);// 分析响应if (response.status() RestStatus.CREATED) {System.out.println(文档已创建);} else if (response.status() RestStatus.OK) {System.out.println(文档已更新);} else {System.err.println(无法创建/更新文档);}// 关闭客户端client.close();}
}二批量写入文档
在 Elasticsearch 中批量写入文档通常使用批量索引Bulk IndexingAPI 来实现。允许一次性将多个文档索引到索引中提高了性能和效率。要批量写入文档可以使用 Bulk API 发送一批索引请求。
POST /your_index/_bulk
{index:{_id:1}}
{field1:value1,field2:value2}
{index:{_id:2}}
{field1:value3,field2:value4}
{update:{_id:3}}
{doc:{field1:new_value}}
{delete:{_id:4}}POST 请求用于批量操作。/your_index 是您的索引名称。使用 {index: {_id: 1}} 定义文档的元数据包括文档标识符。每个文档的数据在之后的行中提供以JSON格式表示。
分析说明 Bulk API 允许一次性处理多个索引请求包括索引、更新和删除操作。 使用元数据例如 {index: {_id: 1}}可以指定每个文档的唯一标识符。 除了索引操作Bulk API 还支持更新和删除操作。
业务举例
假设您正在构建一个电子商务平台需要批量索引多个产品的信息。以下是一个示例包括DSL和Java演示
DSL语句示例
POST /products/_bulk
{index:{_id:1}}
{product_name:Laptop1,description:High-performance laptop with SSD storage.,price:999.99,in_stock:true}
{index:{_id:2}}
{product_name:Laptop2,description:Affordable laptop for everyday use.,price:599.99,in_stock:true}
{index:{_id:3}}
{product_name:Smartphone1,description:Flagship smartphone with advanced features.,price:799.99,in_stock:false}Java演示
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;import java.io.IOException;
import java.util.concurrent.TimeUnit;public class BulkIndexingExample {public static void main(String[] args) throws IOException {RestHighLevelClient client createElasticsearchClient();// 创建批量请求对象BulkRequest request new BulkRequest();// 添加索引请求request.add(new IndexRequest(products).id(1).source(/* JSON 数据 */));request.add(new IndexRequest(products).id(2).source(/* JSON 数据 */));request.add(new IndexRequest(products).id(3).source(/* JSON 数据 */));// 设置超时时间request.timeout(TimeValue.timeValueMinutes(2));request.timeout(2m);// 执行批量请求BulkResponse bulkResponse client.bulk(request, RequestOptions.DEFAULT);// 分析响应if (bulkResponse.hasFailures()) {System.err.println(批量请求中存在失败的操作);} else {System.out.println(批量请求成功完成);}// 关闭客户端client.close();}
}三更新单条文档
update 操作
在 Elasticsearch 中更新单条文档通常使用 update 操作。要更新单条文档您可以使用 update 操作示例如下
POST /your_index/_update/1
{doc: {field1: new_value1,field2: new_value2}
}
POST 请求用于执行更新操作。/your_index 是您的索引名称。/_update/1 中的 1 是要更新的文档的唯一标识符。在 doc 字段中指定要更新的字段和新值。
分析说明 update 操作允许您仅更新文档的特定字段而不必重写整个文档。这是一种高效的方式来更新文档。 更新操作是部分更新只会修改指定字段的值而不会影响其他字段。
业务举例
假设您正在构建一个博客平台并希望更新特定博客文章的内容。以下是一个示例包括DSL和Java演示
DSL语句示例
POST /blog_posts/_update/123
{doc: {title: Updated Title,content: This is the updated content of the blog post.}
}Java演示
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;import java.io.IOException;
import java.util.Map;public class UpdateSingleDocumentExample {public static void main(String[] args) throws IOException {RestHighLevelClient client createElasticsearchClient();// 创建更新请求UpdateRequest request new UpdateRequest(blog_posts, 123);String jsonString { \doc\: { \title\: \Updated Title\, \content\: \This is the updated content of the blog post.\ } };request.doc(jsonString, XContentType.JSON);// 执行更新请求UpdateResponse response client.update(request, RequestOptions.DEFAULT);// 分析响应if (response.status() RestStatus.OK) {System.out.println(文档已成功更新);} else {System.err.println(无法更新文档);}// 关闭客户端client.close();}
}upsert 操作
upsert 是 Elasticsearch 更新操作中的一个重要概念它允许在更新文档时如果文档不存在则将其插入新增。这在希望更新文档的同时如果文档尚不存在就创建一个新文档的情况下非常有用。要执行 upsert 操作可以在 update 操作中使用 doc_as_upsert 参数示例如下
POST /your_index/_update/1
{doc: {field1: new_value1,field2: new_value2},doc_as_upsert: true
}doc 中指定要更新的字段和新值。doc_as_upsert 设置为 true表示如果文档不存在则将 doc 中的内容插入新增为新文档。
分析说明
当文档存在时upsert 操作与普通更新操作相同更新指定的字段。当文档不存在时upsert 操作会将 doc 中的内容插入为新文档。
业务举例
假设您正在构建一个在线商店想要更新产品的信息同时如果产品不存在则添加新产品。以下是一个示例包括DSL和Java演示
DSL语句示例
POST /products/_update/123
{doc: {product_name: Updated Product,price: 29.99},doc_as_upsert: true
}Java演示
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;import java.io.IOException;public class UpsertExample {public static void main(String[] args) throws IOException {RestHighLevelClient client createElasticsearchClient();// 创建更新请求指定索引名称和文档标识符UpdateRequest request new UpdateRequest(products, 123);// 设置要更新的字段和新值String jsonString { \product_name\: \Updated Product\, \price\: 29.99 };request.doc(jsonString, XContentType.JSON);// 设置doc_as_upsert为true以支持upsertrequest.docAsUpsert(true);// 执行更新请求UpdateResponse response client.update(request, RequestOptions.DEFAULT);// 分析响应if (response.status() RestStatus.CREATED) {System.out.println(文档已创建upsert);} else if (response.status() RestStatus.OK) {System.out.println(文档已成功更新);} else {System.err.println(无法更新文档);}// 关闭客户端client.close();}
}四更新批量文档
如果只有文档的ID列表而没有其他条件来更新文档可以使用 Elasticsearch 的 Bulk API 来批量更新这些文档。Bulk API 不需要DSL语句而是需要一个包含每个文档更新操作的请求列表。每个更新操作通常包括三个部分操作类型update、索引名称、文档ID和更新数据。
POST /_bulk
{update:{_index:your_index,_id:doc1}}
{doc:{field1:new_value1}}
{update:{_index:your_index,_id:doc2}}
{doc:{field2:new_value2}}POST 请求用于执行批量更新操作。_bulk 是Bulk API的端点。对于每个文档首先定义了一个update操作然后指定了索引名称_index和文档ID_id最后提供了要更新的数据。
分析说明
使用Bulk API可以在一个请求中批量执行多个文档更新操作。更新操作包括了要更新的文档的索引名称、文档ID以及要更新的数据。
Java演示
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;import java.io.IOException;
import java.util.List;public class ElasticsearchBulkUpdater {private RestHighLevelClient client;public ElasticsearchBulkUpdater(RestHighLevelClient client) {this.client client;}public void bulkUpdateByIdList(String indexName, ListString docIdList, ListMapString, Object updatedDataList) {try {BulkRequest request new BulkRequest();for (int i 0; i docIdList.size(); i) {String docId docIdList.get(i);String jsonString { \doc\: getJsonString(updatedDataList.get(i)) };request.add(client.updateRequest(indexName, docId).doc(jsonString, XContentType.JSON).docAsUpsert(true));}BulkResponse response client.bulk(request, RequestOptions.DEFAULT);if (response.status() RestStatus.OK) {System.out.println(批量更新成功);} else {System.err.println(批量更新失败);}} catch (IOException e) {System.err.println(执行批量更新时出现IO异常: e.getMessage());// 在此处处理异常情况}}private String getJsonString(MapString, Object updatedData) {// 创建更新文档的JSON字符串// 省略实现细节return jsonString;}// 其他方法和资源清理}五根据条件更新文档
要根据条件更新文档可以使用 Elasticsearch 的 Update By Query API。使用 Update By Query API 来根据条件更新文档。示例如下
POST /your_index/_update_by_query
{script: {source: ctx._source.field1 new_value1; ctx._source.field2 new_value2;},query: {bool: {must: [{term: {field3: value_to_match}},{range: {field4: {gte: 10,lt: 20}}}]}}
}POST 请求用于执行更新操作。/your_index 是您的索引名称。_update_by_query 表示根据查询条件更新文档。在 script 中指定要更新的字段和新值的逻辑。在 query 中定义筛选条件以确定要更新哪些文档。在此示例中我们使用了布尔查询bool并设置了两个条件一个是 field3 必须匹配特定值另一个是 field4 的值必须在10到20之间。
分析说明
使用 Update By Query API您可以根据自定义查询条件更新文档。在 script 部分您可以编写更新逻辑将需要更新的字段设置为新值。在这个示例中我们使用 ctx._source.field1 和 ctx._source.field2 来更新字段。
业务举例
假设您正在管理一个电子商务网站的产品目录并需要根据条件更新产品信息。以下是一个示例包括DSL和Java演示
DSL语句示例
POST /products/_update_by_query
{script: {source: ctx._source.price ctx._source.price * 1.1;},query: {bool: {must: [{term: {category: electronics}},{range: {price: {lt: 100}}}]}}
}Java演示
import org.elasticsearch.action.updatebyquery.UpdateByQueryRequest;
import org.elasticsearch.action.updatebyquery.UpdateByQueryResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.rest.RestStatus;import java.io.IOException;public class UpdateByQueryExample {public static void main(String[] args) throws IOException {RestHighLevelClient client createElasticsearchClient();// 创建 Update By Query 请求UpdateByQueryRequest request new UpdateByQueryRequest(products);// 在脚本中指定更新逻辑request.setScript(ctx._source.price ctx._source.price * 1.1);// 设置查询条件只更新电子产品且价格低于100的产品BoolQueryBuilder boolQuery QueryBuilders.boolQuery().must(QueryBuilders.termQuery(category, electronics)).must(QueryBuilders.rangeQuery(price).lt(100));request.setQuery(boolQuery);// 执行 Update By Query 请求UpdateByQueryResponse response client.updateByQuery(request, RequestOptions.DEFAULT);// 分析响应if (response.status() RestStatus.OK) {System.out.println(文档更新成功);} else {System.err.println(文档更新失败);}// 关闭客户端client.close();}
}六删除单条文档
要删除单条文档可以使用 Elasticsearch 的 Delete API。使用 Delete API 来删除单条文档。示例如下
DELETE /your_index/_doc/your_document_idDELETE 请求用于执行删除操作。/your_index 是您的索引名称。/_doc 表示文档类型根据Elasticsearch的最新版本文档类型通常为_doc。your_document_id 是要删除的文档的唯一标识符。
分析说明
使用 Delete API您可以根据文档的唯一标识符删除单条文档。您需要指定索引名称和文档的唯一标识符来执行删除操作。
业务举例
假设正在管理一个博客平台的文章索引以下是一个示例包括DSL和Java演示用于删除单篇文章
DSL语句示例
DELETE /blog_posts/_doc/12345Java演示
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.rest.RestStatus;import java.io.IOException;public class DeleteSingleDocumentExample {public static void main(String[] args) throws IOException {RestHighLevelClient client createElasticsearchClient();// 创建删除请求DeleteRequest request new DeleteRequest(blog_posts, 12345); // 指定索引名称和文档ID// 执行删除请求DeleteResponse response client.delete(request, RequestOptions.DEFAULT);// 分析响应if (response.status() RestStatus.OK) {System.out.println(文档已成功删除);} else if (response.status() RestStatus.NOT_FOUND) {System.err.println(文档未找到无法删除);} else {System.err.println(无法删除文档);}// 关闭客户端client.close();}
}七批量删除文档
要批量删除文档可以使用 Elasticsearch 的 Bulk API。使用 Bulk API 来批量删除文档。示例如下
POST /your_index/_bulk
{delete:{_index:your_index,_id:doc1}}
{delete:{_index:your_index,_id:doc2}}POST 请求用于执行批量操作。/your_index 是您的索引名称。_bulk 是Bulk API的端点。对于每个文档首先定义了一个delete操作然后指定了索引名称_index和文档ID_id。
分析说明
使用 Bulk API可以在一个请求中批量执行多个文档的删除操作。每个删除操作包括要删除的文档的索引名称和文档ID。
业务举例
假设正在管理一个电子商务网站的订单历史记录并需要批量删除特定日期之前的订单记录。以下是一个示例包括DSL和Java演示
DSL语句示例
POST /order_history/_bulk
{delete:{_index:order_history,_id:order1}}
{delete:{_index:order_history,_id:order2}}Java演示
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.rest.RestStatus;import java.io.IOException;
import java.util.List;public class ElasticsearchBulkDeleter {private RestHighLevelClient client;public ElasticsearchBulkDeleter(RestHighLevelClient client) {this.client client;}public void bulkDeleteByIdList(String indexName, ListString docIdList) {try {BulkRequest request new BulkRequest();for (String docId : docIdList) {request.add(client.deleteRequest(indexName, docId));}BulkResponse response client.bulk(request, RequestOptions.DEFAULT);if (response.status() RestStatus.OK) {System.out.println(批量删除成功);} else {System.err.println(批量删除失败);}} catch (IOException e) {System.err.println(执行批量删除时出现IO异常: e.getMessage());// 在此处处理异常情况}}// 其他方法和资源清理}八根据条件删除文档
要根据条件删除文档可以使用 Elasticsearch 的 Delete By Query API。使用 Delete By Query API 来根据条件删除文档。示例如下
POST /your_index/_delete_by_query
{query: {bool: {must: [{term: {field1: value_to_match}},{range: {field2: {lte: 10}}}]}}
}POST 请求用于执行删除操作。/your_index 是您的索引名称。/_delete_by_query 表示根据查询条件删除文档。在 query 中定义筛选条件以确定要删除哪些文档。在此示例中我们使用了布尔查询bool并设置了两个条件一个是 field1 必须匹配特定值另一个是 field2 的值必须小于或等于10。
分析说明
使用 Delete By Query API可以根据自定义查询条件删除文档。在 query 部分您可以定义要删除的文档的筛选条件。
业务举例
假设正在管理一个文档存储系统需要根据条件删除文档。以下是一个示例包括DSL和Java演示
DSL语句示例
POST /documents/_delete_by_query
{query: {bool: {must: [{term: {category: archived}},{range: {last_modified_date: {lte: 2022-01-01}}}]}}
}Java演示
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequest;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.rest.RestStatus;import java.io.IOException;public class DeleteByQueryExample {public static void main(String[] args) throws IOException {RestHighLevelClient client createElasticsearchClient();// 创建 Delete By Query 请求DeleteByQueryRequest request new DeleteByQueryRequest(documents);// 设置查询条件只删除属于 archived 类别且最后修改日期早于等于 2022-01-01 的文档BoolQueryBuilder boolQuery QueryBuilders.boolQuery().must(QueryBuilders.termQuery(category, archived)).must(QueryBuilders.rangeQuery(last_modified_date).lte(2022-01-01));request.setQuery(boolQuery);// 执行 Delete By Query 请求DeleteByQueryResponse response client.deleteByQuery(request, RequestOptions.DEFAULT);// 分析响应if (response.status() RestStatus.OK) {System.out.println(文档删除成功);} else {System.err.println(文档删除失败);}// 关闭客户端client.close();}
}九示例 Elasticsearch 操作工具类
package org.zyf.javabasic.es;import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;import java.io.IOException;
import java.util.List;
import java.util.Map;/*** program: zyfboot-javabasic* description: Elasticsearch 操作工具类的简化示例* author: zhangyanfeng* create: 2023-10-06 22:29**/
public class ElasticsearchOperations {private RestHighLevelClient client;public ElasticsearchOperations(RestHighLevelClient client) {this.client client;}public void singleIndexDoc(String indexName, String indexId, MapString, Object dataMap) {// 实现单条写入文档的逻辑类似于之前示例中的单条写入代码try {IndexRequest request new IndexRequest(indexName).id(indexId).source(dataMap, XContentType.JSON);IndexResponse response client.index(request, RequestOptions.DEFAULT);if (response.status() RestStatus.CREATED) {System.out.println(文档已创建);} else {System.err.println(无法创建文档);}} catch (IOException e) {System.err.println(执行单条写入文档时出现IO异常: e.getMessage());// 在此处处理异常情况}}public void bulkIndexDoc(String indexName, String docIdKey, ListMapString, Object recordMapList) {// 实现批量写入文档的逻辑类似于之前示例中的批量写入代码try {BulkRequest request new BulkRequest();for (MapString, Object recordMap : recordMapList) {String docId recordMap.get(docIdKey).toString();request.add(new IndexRequest(indexName).id(docId).source(recordMap, XContentType.JSON));}BulkResponse response client.bulk(request, RequestOptions.DEFAULT);if (response.status() RestStatus.OK) {System.out.println(批量写入成功);} else {System.err.println(批量写入失败);}} catch (IOException e) {System.err.println(执行批量写入文档时出现IO异常: e.getMessage());// 在此处处理异常情况}}public void singleUpdate(String indexName, String docIdKey, MapString, Object recordMap) {// 实现单条更新文档的逻辑类似于之前示例中的单条更新代码try {String docId recordMap.get(docIdKey).toString();UpdateRequest request new UpdateRequest(indexName, docId).doc(recordMap, XContentType.JSON);UpdateResponse response client.update(request, RequestOptions.DEFAULT);if (response.status() RestStatus.OK) {System.out.println(文档已成功更新);} else {System.err.println(无法更新文档);}} catch (IOException e) {System.err.println(执行单条更新文档时出现IO异常: e.getMessage());// 在此处处理异常情况}}public void bulkUpdate(String indexName, String docIdKey, ListMapString, Object recordMapList) {// 实现批量更新文档的逻辑类似于之前示例中的批量更新代码try {BulkRequest request new BulkRequest();for (MapString, Object recordMap : recordMapList) {String docId recordMap.get(docIdKey).toString();request.add(new UpdateRequest(indexName, docId).doc(recordMap, XContentType.JSON));}BulkResponse response client.bulk(request, RequestOptions.DEFAULT);if (response.status() RestStatus.OK) {System.out.println(批量更新成功);} else {System.err.println(批量更新失败);}} catch (IOException e) {System.err.println(执行批量更新文档时出现IO异常: e.getMessage());// 在此处处理异常情况}}public void singleDelete(String indexName, String docId) {// 实现单条删除文档的逻辑类似于之前示例中的单条删除代码try {DeleteRequest request new DeleteRequest(indexName, docId);DeleteResponse response client.delete(request, RequestOptions.DEFAULT);if (response.status() RestStatus.OK) {System.out.println(文档已成功删除);} else {System.err.println(无法删除文档);}} catch (IOException e) {System.err.println(执行单条删除文档时出现IO异常: e.getMessage());// 在此处处理异常情况}}public void bulkDelete(String indexName, ListString docIdList) {// 实现批量删除文档的逻辑类似于之前示例中的批量删除代码try {BulkRequest request new BulkRequest();for (String docId : docIdList) {request.add(new DeleteRequest(indexName, docId));}BulkResponse response client.bulk(request, RequestOptions.DEFAULT);if (response.status() RestStatus.OK) {System.out.println(批量删除成功);} else {System.err.println(批量删除失败);}} catch (IOException e) {System.err.println(执行批量删除文档时出现IO异常: e.getMessage());// 在此处处理异常情况}}public void deleteByQuery(String indexName, MapString, Object query) {// 实现根据条件删除文档的逻辑类似于之前示例中的 Delete By Query 代码try {// 创建 Delete By Query 请求DeleteByQueryRequest request new DeleteByQueryRequest(indexName);// 设置查询条件BoolQueryBuilder boolQuery QueryBuilders.boolQuery();for (Map.EntryString, Object entry : query.entrySet()) {boolQuery.must(QueryBuilders.matchQuery(entry.getKey(), entry.getValue()));}request.setQuery(boolQuery);// 执行 Delete By Query 请求DeleteByQueryResponse response client.deleteByQuery(request, RequestOptions.DEFAULT);if (response.status() RestStatus.OK) {System.out.println(文档删除成功);} else {System.err.println(文档删除失败);}} catch (IOException e) {System.err.println(执行根据条件删除文档时出现IO异常: e.getMessage());// 在此处处理异常情况}}// 可以添加其他操作方法根据实际需求扩展public void closeClient() {try {client.close();} catch (IOException e) {System.err.println(关闭 Elasticsearch 客户端时出现异常: e.getMessage());}}
}四、搜索操作
搜索操作是 Elasticsearch 的核心功能之一它使您能够以高效的方式从大量数据中检索所需的信息。
一搜索辅助功能
辅助功能一指定返回的字段 二搜索匹配功能 三按字段值排序