ElasticSearch 7.6 多子文档过滤查询

一、es 7.x 父子文档的 field 及官方文档地址

我找了半天,原来官方本来就有教程,只不过专有名词没用对,所以在找官方文档的时候,一直徘徊不前,不说了,先去弄写代码了。后面有时间了在继续写。

es 关键字详解
es 7.x 支持的 field

es 7.x 父子文档 Join,
es 7.x search request API
es 7.6 Java High Level REST Client API
es 各种 Client

以下例子皆是以 es 7.6.0 基础上进行的,docker 安装方便快捷。记得安装 kibana

二、父子文档结构设计

  1. 这里需要注意一下,就是对于一些特定的属性最好在建立文档的时候就进行定义,比如 date 类型,可以接收什么类型的,boolean、数组、对象等。
    在这里插入图片描述

1. 总结构

PUT kikuu_test_product

{
    "settings": {
        "number_of_shards": 2,
        "number_of_replicas": 0,
        "refresh_interval": "50s"
    },
    "mappings": {
        "properties": {
            "productType": { 
            "type": "join",
                "relations": {
                    "product": [
                    "promotionActivityProduct",
                    "store"
                    ]
                }
            },
            "productStatus": {
                "type": "integer"
            },
            "productName": {
                "type": "keyword"
            },
           "productPrice": {
                "type": "keyword"
            },
           "productLowestPrice": {
                "type": "double"
            },
            "storeId": {
                "type": "keyword"
            },
            "storeStatus":{
                "type":"integer"
            },
            "startDate":{
                "type": "date",
                "format": "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd || epoch_millis"
            },
            "endDate":{
                "type": "date",
                "format": "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd || epoch_millis"
            }
        }
    }
}

//如果后面还想再加数据的 field
PUT kikuu_test_product/_mapping
{
  "properties":{
    "startDate":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd || epoch_millis"
    },
    "endDate":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd || epoch_millis"
    }
  }
}

2. 插入测试数据

如果在原来结构的基础上在添加新的 field,那么 es 会自动识别,极有可能识别出来的 field 的类型是 keyword

所以在设计 es 数据结构的时候,最好把重要的一些结构进行定义,以防止后面 es 自动识别成 keyword

① 父文档数据

以下是测试数据 ,request Rest

PUT kikuu_test_product/_doc/1?refresh
{
    "productType": {
        "name":"product"
    },
    "productName":"skirt",
    "productPrice":"221.005",
    "storeNumber":14384,
    "storeId":1,
    "productStatus":3
}

执行该请求 100 次 每次需要改一些内容,我是直接使用数据库里面的数据取表后在网站执行 excel 转 json 后用代码执行的。
如果懒的找我提供一下。
需要提前配置 High Level Rest Client

@Data
@Document(indexName = "kikuu_test_product", shards=2, refreshInterval="-1")
public static class ESProduct {
    
    
    String id;
    Integer productStatus;
    String productName;
    BigDecimal productPrice;
    Long storeId;
    ProductType productType = new ProductType();

	public static class ProductType {
    
    
        String name = "product";
    }
}
    
	public static String getProductJsonString() {
    
    
        return  "{\"list\":[{\"id\":\"17\",\"productStatus\":\"3\",\"productName\":\"14K Necklace Inlayed Stone (03107A-01)\",\"productPrice\":\"5\",\"storeId\":\"1\"},{\"id\":\"19\",\"productStatus\":\"3\",\"productName\":\"14K Necklace Inlayed Stone (03108A-01)\",\"productPrice\":\"5\",\"storeId\":\"1\"},{\"id\":\"20\",\"productStatus\":\"3\",\"productName\":\"14K Necklace Inlayed Stone (03109A-01)\",\"productPrice\":\"8\",\"storeId\":\"1\"},{\"id\":\"21\",\"productStatus\":\"3\",\"productName\":\"14K Necklace Inlayed Stone (03110A-01)\",\"productPrice\":\"5\",\"storeId\":\"1\"},{\"id\":\"22\",\"productStatus\":\"3\",\"productName\":\"14K Necklace Inlayed Stone (03111A-01)\",\"productPrice\":\"8\",\"storeId\":\"1\"},{\"id\":\"23\",\"productStatus\":\"3\",\"productName\":\"14K bracelet (04122A-01)\",\"productPrice\":\"5\",\"storeId\":\"1\"},{\"id\":\"24\",\"productStatus\":\"3\",\"productName\":\"14K Suit Inlayed Stone (07123A)\",\"productPrice\":\"13\",\"storeId\":\"1\"},{\"id\":\"25\",\"productStatus\":\"3\",\"productName\":\"14K Suit Inlayed Stone (07124A)\",\"productPrice\":\"6\",\"storeId\":\"1\"},{\"id\":\"26\",\"productStatus\":\"3\",\"productName\":\"14K Suit Inlayed Stone (07125A)\",\"productPrice\":\"6\",\"storeId\":\"1\"},{\"id\":\"27\",\"productStatus\":\"3\",\"productName\":\"14K Suit Inlayed Stone (07126A)\",\"productPrice\":\"9\",\"storeId\":\"1\"},{\"id\":\"28\",\"productStatus\":\"3\",\"productName\":\"14K Suit Inlayed Stone (07127A)\",\"productPrice\":\"12\",\"storeId\":\"1\"},{\"id\":\"29\",\"productStatus\":\"3\",\"productName\":\"14K Suit Inlayed Stone (07128A)\",\"productPrice\":\"13\",\"storeId\":\"1\"},{\"id\":\"30\",\"productStatus\":\"3\",\"productName\":\"4 shoolbag\",\"productPrice\":\"9\",\"storeId\":\"1\"},{\"id\":\"31\",\"productStatus\":\"3\",\"productName\":\"14K Suit Inlayed Stone (07130A)\",\"productPrice\":\"11\",\"storeId\":\"1\"},{\"id\":\"32\",\"productStatus\":\"3\",\"productName\":\"18K Bracelet Inlayed Stone (04131A-02)\",\"productPrice\":\"10\",\"storeId\":\"1\"},{\"id\":\"33\",\"productStatus\":\"3\",\"productName\":\"4 skirt\",\"productPrice\":\"10\",\"storeId\":\"1\"},{\"id\":\"34\",\"productStatus\":\"3\",\"productName\":\"18K Bracelet Inlayed Stone (04133A-02)\",\"productPrice\":\"11\",\"storeId\":\"1\"},{\"id\":\"35\",\"productStatus\":\"3\",\"productName\":\"18K Bracelet Inlayed Stone (04134A-02)\",\"productPrice\":\"7\",\"storeId\":\"1\"},{\"id\":\"36\",\"productStatus\":\"3\",\"productName\":\"14K Bracelet Inlayed Stone (04135A-01)\",\"productPrice\":\"5\",\"storeId\":\"1\"},{\"id\":\"37\",\"productStatus\":\"3\",\"productName\":\"18K Bracelet Inlayed Stone (04136A-02)\",\"productPrice\":\"26\",\"storeId\":\"1\"},{\"id\":\"38\",\"productStatus\":\"3\",\"productName\":\"18K Two Bracelets (04137A-02)\",\"productPrice\":\"11\",\"storeId\":\"1\"},{\"id\":\"39\",\"productStatus\":\"3\",\"productName\":\"18K Bracelet Inlayed Stone (04138A-02)\",\"productPrice\":\"15\",\"storeId\":\"1\"},{\"id\":\"40\",\"productStatus\":\"3\",\"productName\":\"uuu\",\"productPrice\":\"10\",\"storeId\":\"1\"},{\"id\":\"41\",\"productStatus\":\"3\",\"productName\":\"14K Bracelet Inlayed Stone (04141A-01)\",\"productPrice\":\"6\",\"storeId\":\"1\"},{\"id\":\"42\",\"productStatus\":\"3\",\"productName\":\"14K Bracelet Inlayed Stone (04142A-01)\",\"productPrice\":\"6\",\"storeId\":\"1\"},{\"id\":\"43\",\"productStatus\":\"3\",\"productName\":\"14K Bracelet Inlayed Stone (04143A-01)\",\"productPrice\":\"15\",\"storeId\":\"1\"},{\"id\":\"44\",\"productStatus\":\"3\",\"productName\":\"uuu\",\"productPrice\":\"16\",\"storeId\":\"1\"},{\"id\":\"45\",\"productStatus\":\"3\",\"productName\":\"14K Bracelet Inlayed Stone (04145A-01)\",\"productPrice\":\"14\",\"storeId\":\"1\"},{\"id\":\"46\",\"productStatus\":\"3\",\"productName\":\"18K Suit Inlayed Stone (07146A)\",\"productPrice\":\"5\",\"storeId\":\"1\"},{\"id\":\"47\",\"productStatus\":\"3\",\"productName\":\"18K Suit Inlayed Stone (07147A)\",\"productPrice\":\"10\",\"storeId\":\"1\"},{\"id\":\"48\",\"productStatus\":\"3\",\"productName\":\"18K Suit Inlayed Stone (07148A)\",\"productPrice\":\"7\",\"storeId\":\"1\"},{\"id\":\"49\",\"productStatus\":\"3\",\"productName\":\"18K Suit Inlayed Stone (07149A)\",\"productPrice\":\"10\",\"storeId\":\"1\"},{\"id\":\"50\",\"productStatus\":\"3\",\"productName\":\"18K Suit Inlayed Stone (07150A)\",\"productPrice\":\"12\",\"storeId\":\"1\"},{\"id\":\"51\",\"productStatus\":\"3\",\"productName\":\"18K Suit Inlayed Stone (07151A)\",\"productPrice\":\"13\",\"storeId\":\"1\"},{\"id\":\"52\",\"productStatus\":\"3\",\"productName\":\"18K Suit Inlayed Stone (07152A)\",\"productPrice\":\"10\",\"storeId\":\"1\"},{\"id\":\"54\",\"productStatus\":\"0\",\"productName\":\"123 shirt\",\"productPrice\":\"10\",\"storeId\":\"1\"},{\"id\":\"60\",\"productStatus\":\"3\",\"productName\":\"18K Gold Plated Necklace Fashion Street\",\"productPrice\":\"5\",\"storeId\":\"1\"},{\"id\":\"61\",\"productStatus\":\"3\",\"productName\":\"18K Gold Plated Necklace Fashion Street (03007A-05)\",\"productPrice\":\"5\",\"storeId\":\"1\"},{\"id\":\"62\",\"productStatus\":\"3\",\"productName\":\"18K Gold Plated Fashion Court Necklace\",\"productPrice\":\"7\",\"storeId\":\"1\"},{\"id\":\"63\",\"productStatus\":\"3\",\"productName\":\"18K Street Fashion Necklace(03013A-05)\",\"productPrice\":\"4\",\"storeId\":\"1\"},{\"id\":\"64\",\"productStatus\":\"3\",\"productName\":\"18K Gold Plated Necklace (03017A-05)\",\"productPrice\":\"4\",\"storeId\":\"1\"},{\"id\":\"67\",\"productStatus\":\"3\",\"productName\":\"18 K Gold-Plated Palace Style Necklace (07004A-05)\",\"productPrice\":\"5\",\"storeId\":\"1\"},{\"id\":\"69\",\"productStatus\":\"3\",\"productName\":\"18 K Gold Plated Women's Bracelet (05001A-05)\",\"productPrice\":\"3\",\"storeId\":\"1\"},{\"id\":\"70\",\"productStatus\":\"3\",\"productName\":\"18 K Gold Plated Women's Bracelet (05003A-05)\",\"productPrice\":\"3\",\"storeId\":\"1\"},{\"id\":\"71\",\"productStatus\":\"3\",\"productName\":\"18 K Gold Plated Scripture Bracelet (05005A-05)\",\"productPrice\":\"9\",\"storeId\":\"1\"},{\"id\":\"73\",\"productStatus\":\"3\",\"productName\":\"18 K Gold Plated women's Bracelet (05007A-05)\",\"productPrice\":\"6\",\"storeId\":\"1\"},{\"id\":\"74\",\"productStatus\":\"3\",\"productName\":\"18 K Gold Plated Bracelet (05008A-05)\",\"productPrice\":\"3\",\"storeId\":\"1\"},{\"id\":\"85\",\"productStatus\":\"20\",\"productName\":\"TEST01\",\"productPrice\":\"10\",\"storeId\":\"1\"},{\"id\":\"86\",\"productStatus\":\"20\",\"productName\":\"Retro flowers mother-of-pearl Mosaic gold bracelet \",\"productPrice\":\"7\",\"storeId\":\"1\"},{\"id\":\"87\",\"productStatus\":\"20\",\"productName\":\"Product IMG Test\",\"productPrice\":\"10\",\"storeId\":\"1\"},{\"id\":\"88\",\"productStatus\":\"20\",\"productName\":\"Retro flower hollow out pattern jewelry set\",\"productPrice\":\"11\",\"storeId\":\"1\"},{\"id\":\"89\",\"productStatus\":\"3\",\"productName\":\"Zircon allergy free small dolphin pendant\",\"productPrice\":\"3\",\"storeId\":\"1\"},{\"id\":\"90\",\"productStatus\":\"20\",\"productName\":\"Palace restoring ancient ways suit flowers\",\"productPrice\":\"6\",\"storeId\":\"1\"},{\"id\":\"91\",\"productStatus\":\"3\",\"productName\":\"Color zircon bracelets\",\"productPrice\":\"9\",\"storeId\":\"1\"},{\"id\":\"92\",\"productStatus\":\"3\",\"productName\":\"Auspicious phoenix bangles\",\"productPrice\":\"5\",\"storeId\":\"1\"},{\"id\":\"93\",\"productStatus\":\"3\",\"productName\":\"Lily Chinese style bracelet\",\"productPrice\":\"6\",\"storeId\":\"1\"},{\"id\":\"94\",\"productStatus\":\"3\",\"productName\":\"Gold-plated fashion twisted rope long necklace\",\"productPrice\":\"7\",\"storeId\":\"1\"},{\"id\":\"95\",\"productStatus\":\"20\",\"productName\":\"Elegant color restoring ancient ways earrings\",\"productPrice\":\"3\",\"storeId\":\"1\"},{\"id\":\"96\",\"productStatus\":\"3\",\"productName\":\"图片转移\",\"productPrice\":\"20\",\"storeId\":\"1\"},{\"id\":\"97\",\"productStatus\":\"3\",\"productName\":\"TEST Product\",\"productPrice\":\"10\",\"storeId\":\"1\"},{\"id\":\"98\",\"productStatus\":\"3\",\"productName\":\"TEST Product\",\"productPrice\":\"2\",\"storeId\":\"1\"},{\"id\":\"99\",\"productStatus\":\"20\",\"productName\":\"TEST Product\",\"productPrice\":\"2\",\"storeId\":\"1\"},{\"id\":\"100\",\"productStatus\":\"3\",\"productName\":\"好东西\",\"productPrice\":\"2\",\"storeId\":\"1\"},{\"id\":\"101\",\"productStatus\":\"20\",\"productName\":\"TEST-Product-1\",\"productPrice\":\"2\",\"storeId\":\"1\"},{\"id\":\"102\",\"productStatus\":\"3\",\"productName\":\"Sexy have administrative levels feeling of the ear ring\",\"productPrice\":\"3\",\"storeId\":\"1\"},{\"id\":\"107\",\"productStatus\":\"20\",\"productName\":\"Grimace Gauze Mask\",\"productPrice\":\"3\",\"storeId\":\"3\"},{\"id\":\"108\",\"productStatus\":\"20\",\"productName\":\"Hollow Beads Earrings\",\"productPrice\":\"4\",\"storeId\":\"3\"},{\"id\":\"109\",\"productStatus\":\"20\",\"productName\":\"Pirate Hollow Earrings\",\"productPrice\":\"3\",\"storeId\":\"3\"},{\"id\":\"110\",\"productStatus\":\"20\",\"productName\":\"Hollow Party Mask\",\"productPrice\":\"3\",\"storeId\":\"3\"},{\"id\":\"111\",\"productStatus\":\"3\",\"productName\":\"Flower Hollow Bracelet\",\"productPrice\":\"4\",\"storeId\":\"3\"},{\"id\":\"112\",\"productStatus\":\"3\",\"productName\":\"Pumpkin Hollow Brooch\",\"productPrice\":\"5\",\"storeId\":\"3\"},{\"id\":\"113\",\"productStatus\":\"20\",\"productName\":\"Halloween Lip and Wolf Fang Earrings\",\"productPrice\":\"4\",\"storeId\":\"3\"},{\"id\":\"114\",\"productStatus\":\"20\",\"productName\":\" Solid Color 3D Clutch Bag(PU Synthetic Leather)\",\"productPrice\":\"6\",\"storeId\":\"3\"},{\"id\":\"115\",\"productStatus\":\"20\",\"productName\":\"Cable Chain Bat Pendant Earrings\",\"productPrice\":\"3\",\"storeId\":\"3\"},{\"id\":\"116\",\"productStatus\":\"20\",\"productName\":\"Halloween Color Block Eye Pattern Clutch Bag\",\"productPrice\":\"7\",\"storeId\":\"3\"},{\"id\":\"118\",\"productStatus\":\"3\",\"productName\":\"Halloween Heart Shape Diamante Necklace\",\"productPrice\":\"7\",\"storeId\":\"3\"},{\"id\":\"119\",\"productStatus\":\"20\",\"productName\":\"Halloween Clock Print Wallet\",\"productPrice\":\"8\",\"storeId\":\"3\"},{\"id\":\"121\",\"productStatus\":\"20\",\"productName\":\"Geometric Shoulder Bag(PU Synthetic Leather)\",\"productPrice\":\"40\",\"storeId\":\"3\"},{\"id\":\"123\",\"productStatus\":\"3\",\"productName\":\"Cross-body HandBag\",\"productPrice\":\"37\",\"storeId\":\"3\"},{\"id\":\"124\",\"productStatus\":\"20\",\"productName\":\"Pure Color Shoulder Bag for Women(PVC Faux Leather)\",\"productPrice\":\"40\",\"storeId\":\"3\"},{\"id\":\"127\",\"productStatus\":\"3\",\"productName\":\"CHIC Four sets Tassel Shoulder Bag(PVC Faux Leather)\",\"productPrice\":\"10.6\",\"storeId\":\"3\"},{\"id\":\"132\",\"productStatus\":\"20\",\"productName\":\"Dotted Cutout Dress\",\"productPrice\":\"27\",\"storeId\":\"3\"},{\"id\":\"134\",\"productStatus\":\"20\",\"productName\":\"Print Beaded Hat\",\"productPrice\":\"12\",\"storeId\":\"3\"},{\"id\":\"136\",\"productStatus\":\"3\",\"productName\":\"Skull Geometric Necklace\",\"productPrice\":\"4\",\"storeId\":\"3\"},{\"id\":\"137\",\"productStatus\":\"3\",\"productName\":\"Cloud and Tower Necklace\",\"productPrice\":\"7\",\"storeId\":\"3\"},{\"id\":\"138\",\"productStatus\":\"3\",\"productName\":\"Fireworks gold-plated lovely earrings\",\"productPrice\":\"2\",\"storeId\":\"1\"},{\"id\":\"139\",\"productStatus\":\"3\",\"productName\":\"Hollow Skull Necklace\",\"productPrice\":\"4\",\"storeId\":\"3\"},{\"id\":\"141\",\"productStatus\":\"20\",\"productName\":\"Three-dimensional Floral Sequined Dress\",\"productPrice\":\"27\",\"storeId\":\"3\"},{\"id\":\"142\",\"productStatus\":\"20\",\"productName\":\"Crisscross Backless Dress\",\"productPrice\":\"22\",\"storeId\":\"3\"},{\"id\":\"144\",\"productStatus\":\"20\",\"productName\":\"Backless Strappy Dress\",\"productPrice\":\"24\",\"storeId\":\"3\"},{\"id\":\"145\",\"productStatus\":\"20\",\"productName\":\"Vintage Zipper Dress\",\"productPrice\":\"25\",\"storeId\":\"3\"},{\"id\":\"153\",\"productStatus\":\"3\",\"productName\":\"Purple crystal pendant\",\"productPrice\":\"26\",\"storeId\":\"4\"},{\"id\":\"170\",\"productStatus\":\"20\",\"productName\":\"Bebear Baby Carrier 3 in 1 Carry Ways Front Carry\",\"productPrice\":\"16\",\"storeId\":\"2\"},{\"id\":\"171\",\"productStatus\":\"3\",\"productName\":\"Vintage Chic earrings\",\"productPrice\":\"2\",\"storeId\":\"1\"},{\"id\":\"172\",\"productStatus\":\"3\",\"productName\":\"Fashion square earrings\",\"productPrice\":\"3\",\"storeId\":\"1\"},{\"id\":\"173\",\"productStatus\":\"3\",\"productName\":\"Eyes sparkling stud earrings\",\"productPrice\":\"2\",\"storeId\":\"1\"},{\"id\":\"174\",\"productStatus\":\"20\",\"productName\":\"Bebear Baby Backpack Carrier with Foldable Head Cover\",\"productPrice\":\"23\",\"storeId\":\"2\"},{\"id\":\"175\",\"productStatus\":\"3\",\"productName\":\"Lucky clover earrings\",\"productPrice\":\"2\",\"storeId\":\"1\"},{\"id\":\"176\",\"productStatus\":\"20\",\"productName\":\"Bebear Ergonomic Baby Carrier Baby Sling\",\"productPrice\":\"25\",\"storeId\":\"2\"},{\"id\":\"177\",\"productStatus\":\"20\",\"productName\":\"Bebear Baby Wrap Carrier with Small Pockets\",\"productPrice\":\"18\",\"storeId\":\"2\"}]}";
    }


    public List<ESProduct> getProductList() {
    
    
        List<ESProduct> list = new ArrayList<>();
        JsonObject jsonObject = new JsonParser().parse(getProductJsonString()).getAsJsonObject();
        JsonElement elements = jsonObject.get("list");
        JsonArray asJsonArray = elements.getAsJsonArray();
        for (int i = 0; i < asJsonArray.size(); i++) {
    
    
            String json = asJsonArray.get(i).toString();
            list.add(new Gson().fromJson(json, ESProduct.class));
        }
        return list;
    }

    public static final String TEST_PRODUCT = "kikuu_test_product";
    @Test
    void addDocument() throws IOException {
    
    
        IndexRequest request = new IndexRequest(TEST_PRODUCT);
        List<ESProduct> productList = getProductList();
        for (ESProduct each : productList) {
    
    
            request.id(each.getId());
            request.source(new Gson().toJson(each), XContentType.JSON);
            elasticsearchClient.index(request, RequestOptions.DEFAULT);
        }
    }

② promotionActivityProduct 数据

这个就不给数据了,这个是我自己改的数据。

  1. 平均 5-6 个左右就行了,最好和下面的有交叉 (就是父文档指向的是同一个)
  2. routing 和 parent 需要指向同一个父文档的 id
  3. 一个商品对应一个活动商品
PUT /kikuu_test_product/_doc/a1?routing=22&refresh
{
    "productType": {
        "name":"promotionActivityProduct",
        "parent":"22"
    },
	"activityId": "1212420",
	"startDate": "2021-06-04 00:00:00",
	"endDate": "2021-06-30 00:00:00",
	"ActivityName": "Hot sale"
}

③ 插入子文档 store 数据

  1. 一个商品对应一个店铺
  2. 平均 5-6 个左右就行了,最好和上面的有交叉
  3. storeStatus 状态 == 20 时店铺是正常营业状态。
PUT /kikuu_test_product/_doc/s6?routing=19&refresh
{
    "productType": {
        "name":"store",
        "parent":"19"
    },
    "storeId":"4",
    "storeStatus":20,
    "storeName":"Bebamour"
}

三、request query

官网 API Elasticsearch Reference

// 查询所有文档的productType 为 promotionActivityProduct
GET /kikuu_test_product/_search
{
  "query": {
    //"bool":{
      //"must":{
        "match": {
          //"productType":"product"
          "productType":"promotionActivityProduct"
          //"productType":"store"
        }
      }//,
      //"filter": [
      //  {"range": {"startDate": {"gte":"2021-01-01"}}}
      //]
    //}
  //}
}

// search 按父文档 id 查子文档
GET /kikuu_test_product/_search
{
    "query": {
    "parent_id": { 
      "type": "promotionActivityProduct",
      "id": "19"
    }
  }
}

// 查询所有子文档是 [活动/店铺] 的父文档
GET /kikuu_test_product/_search
{
    "query": {
    "has_child": { 
      "type": "promotionActivityProduct",
      //"type": "store",
      "query" : {
          "match_all" : {}
        }
    }
  }
}

// 查询子文档匹配条件的父文档
GET /kikuu_test_product/_search
{
  "query": {
    "has_child": {
      "type": "promotionActivityProduct",
      "query": {
        //"match_all" : {}
        "bool":{
          "must":{
            "match": {
              "activityId": "1212420"
            }
          }
        }
      }
    }
  }
}

// 查询父文档 根据 子文档满足的条件过滤
GET /kikuu_test_product/_search
{
  "query": {
    "has_child": {
      "type": "promotionActivityProduct",
      //"type":"store",
      "query": {
        "bool": {
          "filter": [
            {"range": {"startDate": {"gte":"2021-01-01"}}},
            {"range":{"endDate":{"lte":"2022-01-31"}}}
            //{"term":{"storeStatus":20}}
          ]
        }
      }
    }
  }
}

// 多子文档按条件过滤
GET /kikuu_test_product/_search
{
  "query": {
    "bool": {
      "filter": [
        {"has_child": {
            "type": "promotionActivityProduct",
            "query": {
              "bool": {
                "filter": [
                  {"range": {"startDate": {"gte": "2021-01-01"}}},
                  {"range": {"endDate": {"lte": "2021-01-31"}}}
                ]
              }
            }
            ,"inner_hits": {}  // 显示对应的子文档
          }
        }
        ,{"has_child":{
            "type":"store",
            "query":{
              "bool":{
                "filter":[
                  {"term":{"storeStatus":20}}
                ]
              }
            }
            ,"inner_hits": {} // 显示对应的子文档
          }
        }
        //,{"range":{"productPrice":{"gte":5}}}
      ]
    }
  }
}

1. SpringBoot Java High Level REST

  1. 以 7.6 版本 为例 High Level REST Client API

① SpringBoot 配置

  1. pom.xml
<!-- 指定引用 es jar 的版本 ,版本一定要匹配-->
    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.6.0</elasticsearch.version>
    </properties>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        
        <!-- gson  -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>
  1. application.properties
# es config
elasticsearch.clustername=docker-cluster
elasticsearch.address=192.168.10.143
elasticsearch.port=9201
  1. config client
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
    
    

    @Value("${elasticsearch.clustername}")
    private String clusterName;

    @Value("${elasticsearch.address}")
    private String searchAddress;

    @Value("${elasticsearch.port}")
    private String port;

    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
    
    
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo(searchAddress+":"+port)
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

② Java High Level REST

    @Autowired
    RestHighLevelClient elasticsearchClient;
    public static final String TEST_PRODUCT = "kikuu_test_product";
    
    /**
     * add product
     * 其实可以使用批量插入的。
     */
    @Test
    void addDocument() throws IOException {
    
    
        IndexRequest request = new IndexRequest(TEST_PRODUCT);
        List<ESProduct> productList = getProductList();
        for (ESProduct each : productList) {
    
    
            request.id(each.getId());
            request.source(new Gson().toJson(each), XContentType.JSON);
            elasticsearchClient.index(request, RequestOptions.DEFAULT);
        }
    }

    /**
     *  add child_doc:activity
     */
    @Test
    void addDocumentActivity() throws IOException {
    
    
    	IndexRequest request = new IndexRequest(TEST_PRODUCT);
        List<ESPromotion> promotionList = common.getPromotion();
        request.id(promotionList.get(1).getId());
        request.source(new Gson().toJson(promotionList.get(1)), XContentType.JSON);
        elasticsearchClient.index(request, RequestOptions.DEFAULT);
        System.out.println(new Gson().toJson(promotionList.get(1)));
        System.out.println(promotionList.get(1).toString());
    }

    /**
     * delete _doc ,
     */
    @Test
    void deleteDocById() throws IOException {
    
    
        DeleteRequest deleteRequest = new DeleteRequest(TEST_PRODUCT, "1");
        // 删除子文档需要指定 routing
        //deleteRequest.routing("1");
        DeleteResponse response = elasticsearchClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(response.getIndex());
        System.out.println(response.status());
        System.out.println(response.toString());
    }
    
    /**
     * search child_doc [promotion] by activityId
     * 满足某个条件删除
     */
    @Test
    void searchDocByKeyword() throws IOException {
    
    
        SearchRequest searchRequest = new SearchRequest(TEST_PRODUCT);
        SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("activityId", "1212420");
        searchBuilder.query(termQueryBuilder);
        searchRequest.source(searchBuilder);

        SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(jsonTransferESPromotion(searchResponse.toString()));
    }

    /**
     * search product
     * 按某个条件查询 product 并转成对象
     */
    @Test
    void searchESProduct() throws IOException {
    
    
        SearchRequest searchRequest = new SearchRequest(TEST_PRODUCT);
        SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
        searchBuilder.query(QueryBuilders.matchQuery("productType", "product"));
        searchBuilder.size(100);

        searchRequest.source(searchBuilder);
        SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
        // ES Object resolving To ESProduct
        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        List<ESProduct> list = new ArrayList<>(120);
        int count = 1;
        System.out.println("<==========================================================     _doc     ==========================================================>");
        for (SearchHit hit : searchHits) {
    
    
            String sourceAsString = hit.getSourceAsString();
            // 单个字符串转对象.
            ESProduct esProduct = new Gson().fromJson(sourceAsString, ESProduct.class);
            list.add(esProduct);
            System.out.println("The " + (count++) +  " product information:" + esProduct.toString());
        }
    }
    
   /**
     * search product filter child _doc
     * when you write query, you should write it first.
     * 查询店铺正常 且当前时间在的活动时间内的商品,
     * 关系含义
     * eq =, neq !=, gt >, gte >=, lt <, lte <=,
     * 过滤多个子文档查询
     */
    @Test
    void searchProductById() throws IOException {
    
    
    	SearchRequest searchRequest = new SearchRequest(TEST_PRODUCT);
        SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
        // 过滤掉 不包含 promotion 的父文档
        BoolQueryBuilder promotionFilter = QueryBuilders.boolQuery();
        promotionFilter.filter(QueryBuilders.rangeQuery("startDate").lte(new Date().getTime()));
        promotionFilter.filter(QueryBuilders.rangeQuery("endDate").gte(new Date().getTime()));
        HasChildQueryBuilder hasChildPromotion = new HasChildQueryBuilder(SearchChildDocType.KIKUU_TEST_PRODUCT_CHILD_DOC_PROMOTION.child, promotionFilter, ScoreMode.Avg);
        hasChildPromotion.innerHit(new InnerHitBuilder().setExplain(true));
        QueryBuilder queryBuilderPro = hasChildPromotion;

        // 过滤掉 不包含 store 的父文档
        BoolQueryBuilder storeFilter = QueryBuilders.boolQuery();
        storeFilter.filter(QueryBuilders.termQuery("storeStatus", 20));
        HasChildQueryBuilder hasChildQueryBuilder = new HasChildQueryBuilder(SearchChildDocType.KIKUU_TEST_PRODUCT_CHILD_DOC_STORE.child, storeFilter, ScoreMode.Avg);
        hasChildQueryBuilder.innerHit(new InnerHitBuilder().setExplain(true));
        QueryBuilder queryBuilderStore = hasChildQueryBuilder;

        BoolQueryBuilder outFilter = QueryBuilders.boolQuery();
        outFilter.filter(queryBuilderPro).filter(queryBuilderStore);

        searchBuilder.query(outFilter);
        searchRequest.source(searchBuilder);
        SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println("\n============================================================\n");
        System.out.println(searchResponse.toString());
    }

官方文档还是给力,写的好。

总结 :所有用请求可以实现的查询条件都可以用代码来实现。

2. other Client。

其他版本请查看官方文档,都有详细介绍,这里就不一一赘述了

猜你喜欢

转载自blog.csdn.net/weixin_44961083/article/details/112802304
7.6