ElasticSearch 7.6 multi-sub-document filtering query

1. Field and official document address of es 7.x parent-child document

I searched for a long time, and it turns out that there are official tutorials, but the proper nouns are useless, so when I was looking for official documents, I kept lingering, let alone, and went to write the code first. I will continue to write later when I have time.

The es keyword explains the fields
supported by es 7.x in detail .

es 7.x parent-child document Join ,
es 7.x search request API
es 7.6 Java High Level REST Client API
es various Clients

The following examples are all based on es 7.6.0, and docker installation is convenient and fast. Remember to install kibana

2. Parent-child document structure design

  1. It should be noted here that it is best to define some specific attributes when creating a document, such as the date type, what type can be received, boolean, array, object, etc.
    insert image description here

1. General structure

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. Insert test data

If a new field is added on the basis of the original structure, then es will automatically recognize it, and it is very likely that the type of field recognized is keyword

Therefore, when designing the es data structure, it is best to define some important structures to prevent es from being automatically recognized as keywords later

① Parent document data

The following is the test data, request Rest

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

Execute the request 100 times and need to change some content each time. I directly use the data in the database to fetch the table and execute the conversion from excel to json on the website and then execute it with code.
If you are lazy, please provide it to me.
High Level Rest Client needs to be configured in advance

@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 data

This is not given the data, this is the data I changed myself.

  1. An average of about 5-6 is enough, and it is best to have an intersection with the following (that is, the parent document points to the same one)
  2. routing and parent need to point to the same parent document id
  3. One product corresponds to one active product
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"
}

③ Insert sub-document store data

  1. One product corresponds to one store
  2. An average of about 5-6 is enough, it is best to have a cross with the above
  3. When storeStatus status == 20, the store is in normal business status.
PUT /kikuu_test_product/_doc/s6?routing=19&refresh
{
    "productType": {
        "name":"store",
        "parent":"19"
    },
    "storeId":"4",
    "storeStatus":20,
    "storeName":"Bebamour"
}

三、request query

Official website 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. Take version 7.6 as an example High Level REST Client API

① SpringBoot configuration

  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());
    }

The official documentation is still awesome and well written.

Summary : All query conditions that can be implemented with requests can be implemented with code.

2. other Client。

For other versions, please refer to the official documents, there are detailed introductions, so I won’t go into details here.

Guess you like

Origin blog.csdn.net/weixin_44961083/article/details/112802304