搜索文档

编辑

索引后的文档几乎可以实时搜索。

有关搜索请求的完整说明,请参阅 Elasticsearch 文档:搜索您的数据查询 DSL搜索 API

简单搜索查询

编辑

可以组合多种类型的搜索查询。我们将从简单的文本匹配查询开始,在 products 索引中搜索自行车。

搜索结果具有 hits 属性,其中包含与查询匹配的文档以及有关索引中存在的匹配总数的信息。

总值带有一个关系,指示总数是精确的(eq — 等于)还是近似的(gte — 大于或等于)。

每个返回的文档都带有其相关性评分以及有关其在索引中位置的其他信息。

String searchText = "bike";

SearchResponse<Product> response = esClient.search(s -> s
    .index("products") 
    .query(q -> q      
        .match(t -> t   
            .field("name")  
            .query(searchText)
        )
    ),
    Product.class      
);

TotalHits total = response.hits().total();
boolean isExactResult = total.relation() == TotalHitsRelation.Eq;

if (isExactResult) {
    logger.info("There are " + total.value() + " results");
} else {
    logger.info("There are more than " + total.value() + " results");
}

List<Hit<Product>> hits = response.hits().hits();
for (Hit<Product> hit: hits) {
    Product product = hit.source();
    logger.info("Found product " + product.getSku() + ", score " + hit.score());
}

我们要搜索的索引的名称。

搜索请求的查询部分(搜索请求还可以有其他组件,例如 聚合)。

从许多可用的查询变体中选择一个。 我们在这里选择匹配查询(全文搜索)。

配置匹配查询:我们在 name 字段中搜索术语。

匹配文档的目标类。 我们在这里使用 Product,就像在 get 请求示例中一样。

get 操作类似,您可以使用相应的目标类而不是 Product(例如 JSON-P 的 JsonValue 或 Jackson 的 ObjectNode)来获取与查询匹配的原始 JSON 文档。

嵌套搜索查询

编辑

Elasticsearch 允许组合单个查询来构建更复杂的搜索请求。 在下面的示例中,我们将搜索价格上限为 200 的自行车。

String searchText = "bike";
double maxPrice = 200.0;

// Search by product name
Query byName = MatchQuery.of(m -> m 
    .field("name")
    .query(searchText)
)._toQuery(); 

// Search by max price
Query byMaxPrice = RangeQuery.of(r -> r
    .number(n -> n
    .field("price")
    .gte(maxPrice)) 
)._toQuery();

// Combine name and price queries to search the product index
SearchResponse<Product> response = esClient.search(s -> s
    .index("products")
    .query(q -> q
        .bool(b -> b 
            .must(byName) 
            .must(byMaxPrice)
        )
    ),
    Product.class
);

List<Hit<Product>> hits = response.hits().hits();
for (Hit<Product> hit: hits) {
    Product product = hit.source();
    logger.info("Found product " + product.getSku() + ", score " + hit.score());
}

我们正在为各个标准分别创建查询。

MatchQuery 是一个查询变体,我们必须将其转换为 Query联合类型。 有关更多详细信息,请参阅 变体类型

Elasticsearch 范围查询接受大范围的值类型。 我们在这里创建最大价格的 JSON 表示形式。

搜索查询是一个布尔查询,它组合了文本搜索和最大价格查询。

两个查询都添加为 must,因为我们希望结果与所有标准匹配。

模板化搜索

编辑

搜索模板是存储的搜索,您可以使用不同的变量运行。 搜索模板使您可以在不修改应用程序代码的情况下更改搜索。

在运行模板搜索之前,您首先必须创建模板。 这是一个存储的脚本,它返回搜索请求正文,并且通常定义为 Mustache 模板。 此存储的脚本可以在应用程序外部创建,也可以使用 Java API 客户端创建

// Create a script
esClient.putScript(r -> r
    .id("query-script") 
    .script(s -> s
        .lang("mustache")
        .source("{\"query\":{\"match\":{\"{{field}}\":\"{{value}}\"}}}")
    ));

要创建的模板脚本的标识符。

要使用搜索模板,请使用 searchTemplate 方法引用脚本并为其参数提供值

SearchTemplateResponse<Product> response = esClient.searchTemplate(r -> r
        .index("some-index")
        .id("query-script") 
        .params("field", JsonData.of("some-field")) 
        .params("value", JsonData.of("some-data")),
    Product.class
);

List<Hit<Product>> hits = response.hits().hits();
for (Hit<Product> hit: hits) {
    Product product = hit.source();
    logger.info("Found product " + product.getSku() + ", score " + hit.score());
}

要使用的模板脚本的标识符。

模板参数值。

有关更多深入信息,请参阅 Elasticsearch 搜索模板文档

上面示例的源代码可以在 Java API 客户端测试中找到。