欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > 百万字文本内容搜索Java实现方案

百万字文本内容搜索Java实现方案

2024/10/23 21:31:31 来源:https://blog.csdn.net/finally_vince/article/details/142921603  浏览:    关键词:百万字文本内容搜索Java实现方案

大家好,我是 V 哥。在处理百万字文本内容搜索的场景中,使用 Elasticsearch 是一个非常合适的选择。Elasticsearch 可以轻松处理大规模文本数据,并提供全文搜索、模糊查询、以及高效的搜索结果排序等功能。本文将提供一个详细的 Java 代码案例,展示如何将百万字文本数据存储到 Elasticsearch 中并实现高效搜索。

方案设计

  1. 数据导入:将百万字的文本数据通过 Java 客户端导入 Elasticsearch 索引。
  2. 全文检索:使用 Elasticsearch 的全文检索功能,支持高效地对大规模文本进行搜索。
  3. 结果高亮显示:将匹配的搜索关键词进行高亮显示,方便用户快速定位。

主要步骤

  1. Elasticsearch Java 客户端配置
  2. 创建索引与映射
  3. 插入百万字文本数据
  4. 实现全文检索与高亮显示

1. Elasticsearch Java 客户端配置

首先,我们需要在 Java 项目中集成 Elasticsearch 客户端。

Maven 依赖

pom.xml 文件中添加 Elasticsearch Java 客户端的依赖:

<dependencies><!-- Elasticsearch Java Client --><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.10.2</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.11.3</version></dependency>
</dependencies>
创建 Elasticsearch 客户端
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.RestClient;
import org.apache.http.HttpHost;public class ESClient {public static RestHighLevelClient createClient() {return new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));}
}

在此例中,我们假设 Elasticsearch 已经在本地运行,端口为 9200

2. 创建索引与映射

我们需要创建一个索引来存储文本数据,并设置索引的映射(mapping)。可以为文本字段配置 text 类型,以支持全文搜索功能。

import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;public class ESIndexManager {public static void createTextIndex(RestHighLevelClient client) throws Exception {CreateIndexRequest request = new CreateIndexRequest("texts");request.settings(Settings.builder().put("index.number_of_shards", 3) // 设置分片.put("index.number_of_replicas", 1) // 设置副本);String mapping = "{\n" +"  \"properties\": {\n" +"    \"title\": {\n" +"      \"type\": \"text\"\n" +"    },\n" +"    \"content\": {\n" +"      \"type\": \"text\",\n" +"      \"analyzer\": \"standard\"\n" +"    }\n" +"  }\n" +"}";request.mapping(mapping, XContentType.JSON);CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);if (createIndexResponse.isAcknowledged()) {System.out.println("Index created successfully.");} else {System.out.println("Index creation failed.");}}
}

3. 插入百万字文本数据

接下来,将百万字的文本数据插入到 Elasticsearch 索引中。假设每篇文章由 titlecontent 组成。

import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.xcontent.XContentFactory;public class ESDataManager {public static void indexDocument(RestHighLevelClient client, String title, String content) throws Exception {IndexRequest request = new IndexRequest("texts");request.source(XContentFactory.jsonBuilder().startObject().field("title", title).field("content", content).endObject());IndexResponse response = client.index(request, RequestOptions.DEFAULT);System.out.println("Indexed document ID: " + response.getId());}public static void bulkInsert(RestHighLevelClient client, List<TextData> dataList) throws Exception {BulkRequest bulkRequest = new BulkRequest();for (TextData data : dataList) {IndexRequest request = new IndexRequest("texts");request.source(XContentFactory.jsonBuilder().startObject().field("title", data.getTitle()).field("content", data.getContent()).endObject());bulkRequest.add(request);}client.bulk(bulkRequest, RequestOptions.DEFAULT);}
}class TextData {private String title;private String content;// Constructors, getters and setters
}

通过 bulkInsert 方法,可以一次性批量插入大量的文本数据,这对于处理大规模数据非常高效。

4. 全文搜索与高亮显示

当文本数据插入完成后,我们就可以实现全文搜索。这里我们展示如何使用 match 查询来搜索文本,并实现高亮显示。

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.SearchHit;public class ESSearchManager {public static void searchWithHighlight(RestHighLevelClient client, String searchText) throws Exception {SearchRequest searchRequest = new SearchRequest("texts");SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// 构建全文搜索的 querysearchSourceBuilder.query(QueryBuilders.matchQuery("content", searchText));// 设置高亮显示HighlightBuilder highlightBuilder = new HighlightBuilder();HighlightBuilder.Field highlightContent = new HighlightBuilder.Field("content");highlightContent.preTags("<em>").postTags("</em>");highlightBuilder.field(highlightContent);searchSourceBuilder.highlighter(highlightBuilder);searchRequest.source(searchSourceBuilder);// 执行搜索SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);// 解析搜索结果并高亮显示for (SearchHit hit : searchResponse.getHits()) {String title = (String) hit.getSourceAsMap().get("title");String content = (String) hit.getSourceAsMap().get("content");System.out.println("Title: " + title);HighlightField highlight = hit.getHighlightFields().get("content");if (highlight != null) {String highlightedContent = String.join(" ", highlight.fragments());System.out.println("Highlighted Content: " + highlightedContent);} else {System.out.println("Content: " + content);}}}
}
搜索示例
public class Main {public static void main(String[] args) throws Exception {RestHighLevelClient client = ESClient.createClient();// 批量插入百万字文本数据List<TextData> dataList = new ArrayList<>();dataList.add(new TextData("Title 1", "This is the first example of a long text content."));dataList.add(new TextData("Title 2", "Another document with interesting content to search."));ESDataManager.bulkInsert(client, dataList);// 全文搜索并高亮显示ESSearchManager.searchWithHighlight(client, "content");// 关闭客户端client.close();}
}

5. 分析

  • 索引设计:为全文搜索设置 text 字段类型,并使用标准分词器进行处理。对于大规模文本数据,合理设置索引的分片数量(number_of_shards)和副本数量(number_of_replicas)以提高索引的性能。
  • 批量导入:在百万字数据量的情况下,使用 bulk 批量导入方式能极大提高插入效率。
  • 全文搜索:通过 matchQuery 对文本内容进行全文搜索,支持多种搜索方式如短语匹配、模糊查询等。
  • 高亮显示:通过 HighlightBuilder 实现对搜索结果中的匹配文本进行高亮显示,帮助用户快速定位关键内容。

6. 总结

通过 Elasticsearch 和 Java 客户端,能够高效地处理大规模文本数据的搜索需求。本文提供了从索引创建、数据插入到全文搜索和高亮显示

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com