es的nested查询

一、一层嵌套
mapping:

PUT /nested_example
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "books": {
        "type": "nested",
        "properties": {
          "title": {
            "type": "text"
          },
          "author": {
            "type": "text"
          }
        }
      }
    }
  }
}

导入数据到索引:


POST /nested_example/_bulk
{ "index" : { "_id" : "1" } }
{ "name" : "John Doe", "books" : [ { "title" : "Book 1", "author" : "Author 1" }, { "title" : "Book 2", "author" : "Author 2" } ] }
{ "index" : { "_id" : "2" } }
{ "name" : "Jane Smith", "books" : [ { "title" : "Book 3", "author" : "Author 3" }, { "title" : "Book 4", "author" : "Author 4" } ] }

使用DevTools执行多层嵌套查询

 POST /nested_example/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "Tom"
          }
        },
        {
          "nested": {
            "path": "books",
            "query": {
              "match": {
                "books.author": "Jerry"
              }
            }
          }
        }
      ]
    }
  }
}

Java查询语句:

 import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
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();

        SearchRequest searchRequest = new SearchRequest("nested_example");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 构建bool查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        // 添加must子句用于匹配name字段为"Tom"
        MatchQueryBuilder nameQuery = QueryBuilders.matchQuery("name", "Tom");
        boolQuery.must(nameQuery);

        // 构建嵌套查询
        NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery(
            "books",
            QueryBuilders.matchQuery("books.author", "Jerry"),
            ScoreMode.None // 可选的分数模式
        );
        boolQuery.must(nestedQuery);

        sourceBuilder.query(boolQuery);
        searchRequest.source(sourceBuilder);

        // 执行查询
        client.search(searchRequest, RequestOptions.DEFAULT);

        // 关闭客户端连接
        client.close();
    }
}


二、多层嵌套
mapping:

PUT /nested_example
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "books": {
        "type": "nested",
        "properties": {
          "title": {
            "type": "text"
          },
          "authors": {
            "type": "nested",
            "properties": {
              "author_name": {
                "type": "text"
              }
            }
          }
        }
      }
    }
  }
}

导入数据到索引

POST /nested_example/_bulk
{ "index" : { "_id" : "1" } }
{ "name" : "John Doe", "books" : [ { "title" : "Book 1", "authors" : [ { "author_name" : "Author 1" }, { "author_name" : "Author 2" } ] } ] }
{ "index" : { "_id" : "2" } }
{ "name" : "Jane Smith", "books" : [ { "title" : "Book 2", "authors" : [ { "author_name" : "Author 2" }, { "author_name" : "Author 3" } ] } ] }

使用DevTools执行多层嵌套查询

POST /nested_example/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "Tom"
          }
        },
        {
          "nested": {
            "path": "books",
            "query": {
              "nested": {
                "path": "books.authors",
                "query": {
                  "match": {
                    "books.authors.author_name": "Author 2"
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

Java查询语句:

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;

public class ElasticsearchNestedNestedQueryExample {
    public static void main(String[] args) throws Exception {
        RestHighLevelClient client = new RestHighLevelClient();

        SearchRequest searchRequest = new SearchRequest("nested_example");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 构建bool查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        // 添加must子句用于匹配name字段为"Tom"
        MatchQueryBuilder nameQuery = QueryBuilders.matchQuery("name", "Tom");
        boolQuery.must(nameQuery);

        // 构建外层nested查询
        NestedQueryBuilder outerNestedQuery = QueryBuilders.nestedQuery(
            "books",
            // 构建内层nested查询
            QueryBuilders.nestedQuery(
                "books.authors",
                QueryBuilders.matchQuery("books.authors.author_name", "Author 2"),
                ScoreMode.None // 可选的分数模式
            ),
            ScoreMode.None // 可选的分数模式
        );

        boolQuery.must(outerNestedQuery);

        sourceBuilder.query(boolQuery);
        searchRequest.source(sourceBuilder);

        // 执行查询
        client.search(searchRequest, RequestOptions.DEFAULT);

        // 关闭客户端连接
        client.close();
    }
}