ES 嵌套查询

背景

一个配方由多种原材料组成,需求是根据各种原材料的用量搜索出对应的配方

配方实体类

java 复制代码
class Formula {

    private long id;

    private String name;

    private List<Material> materials;

}

class Material {

    @JsonProperty("material_id")
    private long materialId;

    private float amount;

}

1、定义索引映射 Mapping

复制代码
PUT /formula
{
  "mappings": {
    "properties": {
      "id": {
        "type": "long"
      },
      "name": {
        "type": "text"
      },
      "materials": {
        "type": "nested",
        "properties": {
          "material_id": {
            "type": "long"
          },
          "amount": {
            "type": "float"
          }
        }
      }
    }
  }
}

2、添加测试数据

复制代码
POST /formula/_doc/1
{
  "id": "1",
  "name": "formula A",
  "materials": [
    { "material_id": "material_1", "amount": 100 },
    { "material_id": "material_2", "amount": 50 }
  ]
}

POST /formula/_doc/2
{
  "id": "2",
  "name": "formula B",
  "materials": [
    { "material_id": "material_2", "amount": 30 },
    { "material_id": "material_3", "amount": 20 }
  ]
}

3、查询

复制代码
GET /formula/_search
{
  "query": {
    "bool": {
        "must": [
            {
                "match": {
                    "name": "formula A"
                }
            },
            {
                "nested": {
                    "path": "materials",
                    "query": {
                        "bool": {
                        "must": [
                            { "match": { "materials.material_id": "2" } },
                            { "range": { "materials.amount": { "gte": 40, "lte": 60 } } }
                        ]
                        }
                    }
                }
            }
        ]
    }
  }
}

RestHighLevelClient

java 复制代码
// nested
BoolQueryBuilder nestedBoolQueryBuilder = new BoolQueryBuilder();
nestedBoolQueryBuilder.must().add(QueryBuilders.matchPhraseQuery("materials.material_id", 1));
nestedBoolQueryBuilder.must().add(QueryBuilders.rangeQuery("materials.amount").from(40).to(60));
NestedQueryBuilder nestedQueryBuilder =  QueryBuilders.nestedQuery("materials", nestedBoolQueryBuilder, ScoreMode.Avg);

// query
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(nestedQueryBuilder);
// simple
boolQueryBuilder.must(QueryBuilders.matchQuery("name", "formula A"));

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(boolQueryBuilder);

SearchRequest searchRequest = new SearchRequest(new String[]{index}, searchSourceBuilder);

// response
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

ElasticsearchClient

java 复制代码
SearchResponse<Formula> response = elasticsearchClient.search(s -> s
                .index("formula")
                .query(q -> q.match(t -> t.field("name").query("formula A")))
                .query(q -> q.nested(nq -> nq.path("materials")
                                .query(nq1 -> nq1.match(t -> t.field("materials.material_id").query("2")))
                                .query(nq2 -> nq2.range(r -> r.field("materials.amount").from("40").to("60")))
                        )
                ),
        Formula.class
);
相关推荐
极限实验室12 小时前
Elasticsearch 备份:snapshot 镜像使用篇
数据库·elasticsearch
gb421528716 小时前
elasticsearch索引多长时间刷新一次(智能刷新索引根据数据条数去更新)
大数据·elasticsearch·jenkins
熊文豪20 小时前
Windows安装Elasticsearch保姆级教程
大数据·windows·elasticsearch·kibana
INFINI Labs2 天前
Elasticsearch 备份:方案篇
大数据·elasticsearch·搜索引擎·gateway·snapshot·backup·ccr
NickBi2 天前
龙芯 LoongArch64编译es7.17.20
后端·elasticsearch
会飞的小蛮猪2 天前
Prometheus运维之路(ES监控接入)
elasticsearch·监控·自动化运维
贝多芬也爱敲代码2 天前
如何减小ES和mysql的同步时间差
大数据·mysql·elasticsearch
深思慎考2 天前
ElasticSearch与Kibana 入门指南(7.x版本)
大数据·elasticsearch·jenkins
problc3 天前
PostgreSQL + Redis + Elasticsearch 实时同步方案实践:从触发器到高性能搜索
redis·elasticsearch·postgresql