MST

星途 面试题库

面试题:ElasticSearch中如何实现命中文档嵌套的基础搜索

假设在ElasticSearch中有一个文档结构,包含多层嵌套对象。例如,有一个‘订单’文档,其中‘订单详情’是嵌套在‘订单’中的对象数组,每个‘订单详情’又包含‘商品’等嵌套信息。请描述如何编写查询来搜索特定商品在特定订单中的记录。
20.3万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试
  1. 使用nested查询
    • Elasticsearch提供了nested查询来处理嵌套对象的搜索。
    • 假设索引名为orders,映射结构已经正确设置,将order_details字段定义为nested类型。
    • 以下是一个基本的查询示例(使用JSON格式):
{
    "query": {
        "nested": {
            "path": "order_details",
            "query": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "order_id": "特定订单ID"
                            }
                        },
                        {
                            "match": {
                                "order_details.product_name": "特定商品名称"
                            }
                        }
                    ]
                }
            }
        }
    }
}
  • 在上述查询中:
    • path指定了嵌套对象的路径,这里是order_details
    • 内部的bool查询用于组合条件。
    • match查询分别针对order_id(假设订单有唯一标识字段order_id)匹配特定订单,以及order_details.product_name匹配特定商品。
  1. 使用DSL在不同语言客户端中的实现
    • Java(使用Elasticsearch High - Level REST Client)
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;

public class ElasticsearchNestedQueryExample {
    public static void main(String[] args) throws Exception {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("localhost", 9200, "http")));

        SearchRequest searchRequest = new SearchRequest("orders");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery("order_id", "特定订单ID"));
        boolQueryBuilder.must(QueryBuilders.matchQuery("order_details.product_name", "特定商品名称"));

        NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("order_details", boolQueryBuilder, ScoreMode.None);

        searchSourceBuilder.query(nestedQueryBuilder);
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        // 处理搜索结果
        client.close();
    }
}
  • Python(使用elasticsearch - py库)
from elasticsearch import Elasticsearch

es = Elasticsearch([{'host': 'localhost', 'port': 9200}])

body = {
    "query": {
        "nested": {
            "path": "order_details",
            "query": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "order_id": "特定订单ID"
                            }
                        },
                        {
                            "match": {
                                "order_details.product_name": "特定商品名称"
                            }
                        }
                    ]
                }
            }
        }
    }
}

result = es.search(index='orders', body=body)
print(result)

这些方法可以帮助你在Elasticsearch中搜索特定商品在特定订单中的记录。需要注意的是,实际应用中应根据具体的映射结构和数据情况适当调整查询。