ES概述
ES (Elasticsearch) 是一个分布式的搜索和分析引擎,它支持使用一种类似于 SQL 的查询语法,称为 Elasticsearch 查询语法。以下是 Elasticsearch 查询语法的基本概念和语法结构:
-
索引 (Index):Elasticsearch 中的数据存储在索引中,一个索引包含多个文档,每个文档都有一个唯一的 ID。
-
类型 (Type):索引可以包含多个类型,每个类型定义了一组字段。
-
字段 (Field):类型中的每个字段都有一个名称和类型,可以包含单个值或多个值。
-
映射 (Mapping):定义了文档如何被存储和索引的方式。
-
查询 (Query):用于搜索索引中的文档,可以使用各种查询类型,如全文搜索、精确匹配、范围查询等。
常用ES语法
以下是一些常用的 Elasticsearch 查询语法示例:
匹配查询 (Match Query): 用于执行全文搜索,可以通过指定要搜索的字段和要搜索的文本来进行搜索。
GET /my_index/my_type/_search
{
"query": {
"match": {
"title": "quick brown fox"
}
}
}
多字段匹配查询 (Multi-match Query): 与匹配查询类似,但可以在多个字段中搜索。
GET /my_index/my_type/_search
{
"query": {
"multi_match": {
"query": "quick brown fox",
"fields": ["title", "content"]
}
}
}
范围查询 (Range Query): 用于搜索一个范围内的值。
GET /my_index/my_type/_search
{
"query": {
"range": {
"age": {
"gte": 18,
"lte": 30
}
}
}
}
布尔查询 (Boolean Query): 用于组合多个查询,可以使用 AND、OR、NOT 运算符组合查询
GET /my_index/my_type/_search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "quick" }},
{ "match": { "title": "brown" }}
],
"must_not": [
{ "match": { "title": "dog" }}
]
}
}
}
模糊查询 (Fuzzy Query): 用于搜索与给定文本相似的文档,可以在一定程度上处理拼写错误。
GET /my_index/my_type/_search
{
"query": {
"fuzzy": {
"title": {
"value": "fox",
"fuzziness": "2"
}
}
}
}
前缀查询 (Prefix Query): 用于搜索以指定前缀开头的文档。
GET /my_index/my_type/_search
{
"query": {
"prefix": {
"title": "qu"
}
}
}
正则表达式查询 (Regexp Query): 用于搜索与指定正则表达式匹配的文档。
GET /my_index/my_type/_search
{
"query": {
"regexp": {
"title": "q[a-z]*k"
}
}
}
短语查询 (Phrase Query): 用于搜索包含指定短语的文档。
GET /my_index/my_type/_search
{
"query": {
"match_phrase": {
"title": "quick brown"
}
}
}
聚合查询 (Aggregation Query): 用于对搜索结果进行分组和计算统计信息,例如求平均值、最大值、最小值等
GET /my_index/my_type/_search
{
"query": {
"match_all": {}
},
"aggs": {
"avg_age": {
"avg": {
"field": "age"
}
}
}
}
Java ES示例
Java API 连接 Elasticsearch 并进行搜索的简单示例:
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.unit.TimeValue;
import java.io.IOException;
public class ElasticsearchExample {
private static final String INDEX_NAME = "my_index";
private static final String TYPE_NAME = "my_type";
private static final String HOST_NAME = "localhost";
private static final int PORT_NUMBER = 9200;
public static void main(String[] args) {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(HOST_NAME, PORT_NUMBER));
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
searchRequest.types(TYPE_NAME);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("title", "quick brown"));
searchSourceBuilder.from(0);
searchSourceBuilder.size(10);
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(searchSourceBuilder);
try {
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
此示例首先创建了一个 RestHighLevelClient 对象,该对象将用于连接 Elasticsearch。然后,创建一个 SearchRequest 对象,该对象指定要搜索的索引和类型,并设置搜索条件。接下来,使用 SearchSourceBuilder 对象指定搜索条件的详细信息,如匹配查询、分页和超时时间等。最后,调用 client.search() 方法执行搜索并处理结果。
请注意,此示例中使用的 Elasticsearch 版本是 6.x,如果您使用的是不同的版本,则需要相应地调整代码。另外,为了简化示例,没有包含异常处理和资源管理代码,实际上需要根据具体情况进行处理。
常用ES方法
以下是一些 Java API 中常用的 Elasticsearch 方法:
连接 Elasticsearch 集群:
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
索引文档:
IndexRequest request = new IndexRequest("my_index", "my_type", "1");
String jsonString = "{" +
"\"title\":\"example title\"," +
"\"content\":\"example content\"" +
"}";
request.source(jsonString, XContentType.JSON);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
更新文档:
UpdateRequest request = new UpdateRequest("my_index", "my_type", "1");
String jsonString = "{" +
"\"title\":\"updated title\"" +
"}";
request.doc(jsonString, XContentType.JSON);
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
获取文档:
GetRequest request = new GetRequest("my_index", "my_type", "1");
GetResponse response = client.get(request, RequestOptions.DEFAULT);
删除文档:
DeleteRequest request = new DeleteRequest("my_index", "my_type", "1");
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
执行搜索:
SearchRequest request = new SearchRequest("my_index");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchQuery("title", "example"));
sourceBuilder.from(0);
sourceBuilder.size(10);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
创建索引:
CreateIndexRequest request = new CreateIndexRequest("my_index");
request.settings(Settings.builder()
.put("index.number_of_shards", 1)
.put("index.number_of_replicas", 2));
request.mapping("my_type", "title", "type=text");
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
删除索引:
DeleteIndexRequest request = new DeleteIndexRequest("my_index");
AcknowledgeResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
使用ES常用优化建议
使用 Java API 连接 Elasticsearch 时查询优化的一些建议:
-
使用合适的查询类型:Elasticsearch 支持多种查询类型,包括精确匹配、模糊匹配、范围查询、全文搜索等。根据查询的需求选择最合适的查询类型可以提高查询效率。
-
使用查询语法:使用查询语法可以更精确地指定查询条件和过滤条件,避免在结果中返回不必要的数据。Elasticsearch 查询语法包括布尔查询、范围查询、通配符查询、正则表达式查询、前缀查询、短语查询等。
-
使用索引优化:合理设计索引结构可以显著提高查询效率。例如,为高频查询的字段创建索引、避免创建大量冗余字段、使用合适的分词器等。
-
缓存查询结果:如果某个查询经常被使用,并且查询结果比较稳定,可以考虑将查询结果缓存起来。这可以减少查询次数和查询时间,提高查询效率。
-
批量查询:将多个查询合并为一个批量查询可以减少网络传输时间和资源消耗。使用批量查询可以将多个查询一起发送给 Elasticsearch,并在一次请求中获取多个结果。
-
使用聚合:使用聚合可以对查询结果进行分组、统计、排序等操作。聚合操作通常比单独的查询更加高效,因为它可以在 Elasticsearch 内部进行操作,而不需要在客户端进行处理。
-
避免过多数据:当查询结果集非常大时,应该考虑限制返回的结果数量,或者使用滚动查询等技术进行分批处理。这可以避免在客户端处理过多的数据,导致内存溢出或性能下降。
总之,优化查询可以显著提高 Elasticsearch 查询的性能和效率。使用合适的查询类型、查询语法、索引优化、缓存查询结果、批量查询、聚合等技术可以帮助我们提高查询效率,减少资源消耗,同时提高系统的可靠性和稳定性。
使用ES注意事项
使用 Java API 连接 Elasticsearch 时需要注意的一些事项:
-
版本兼容性:确保使用的 Java API 版本与 Elasticsearch 版本兼容。建议使用最新版本的 Java API 和 Elasticsearch,以获得最佳性能和功能。
-
资源管理:确保在使用完资源后正确地关闭它们,例如关闭连接、释放内存等。不正确的资源管理可能会导致内存泄漏或连接池耗尽等问题。
-
错误处理:当使用 Java API 与 Elasticsearch 通信时,可能会出现各种类型的错误,例如网络故障、索引不存在等。确保在代码中包含适当的错误处理,以便在出现问题时进行恰当的处理。
-
查询优化:优化查询可以提高搜索性能和减少资源消耗。建议使用合适的查询类型、正确的查询语法和索引结构,以最大程度地提高搜索效率。
-
安全性:确保在连接 Elasticsearch 集群时使用适当的安全设置,例如身份验证、TLS/SSL 加密等。这有助于保护数据和防止未经授权的访问。
-
性能测试:在生产环境之前,建议进行性能测试以确保系统能够处理预期的负载并满足性能要求。可以使用诸如 JMeter 等性能测试工具对 Elasticsearch 进行负载测试。
总的来说,使用 Java API 连接 Elasticsearch 需要谨慎处理,确保代码正确性、资源管理、错误处理、查询优化、安全性和性能测试等方面都得到妥善处理。