YAZONG 我的开源

关于es-painless的基本用法、嵌套字段处理及排序

 
0 评论0 浏览

一、需求模拟

#此篇文章您可以全部复制到Word表格中,可以看的更清楚些。

下面以需求模拟的方式介绍painless的基本用法。

第一个模拟需求,有A、B、C三个价格值,分别代表商品原价、不同城市的价格、促销的价格。判断条件如下:

如果B的城市ID不为空,那么直接返回B的价格;

如果B的城市ID为空,那么判断C的价格,如果C的价格不为空,那么直接返回C的价格,否则返回A的价格。

最终获取判断后的价格,按照判断后的价格升序或降序排列。

第二个模拟需求,依然需要处理上述三个字段并返回最终判断的价格,最终判断价格不排序,但是要按照销售量字段D降序排序。

在ES中,A、B、C和D这三个字段都在同一个索引中,其中B和C的字段分别属于两个嵌套类型字段中的字段(B和C在属于嵌套的集合,一个集合中会有多条数据,现在模拟的数据只会在集合中存在一条数据)。

A对应索引中的shop_price字段。

B对应索引中的city.shop_price字段。

C对应索引中的promotion.shop_price字段。

D对应索引中的purchased_num字段。

二、索引模拟结构

#索引名称goods_detail_one_source_a

{
  "mappings": {
    "goods_detail_one_type":{
      "properties": {
        "goods_id": {
          "type": "keyword",
          "store": "true"
        },
        "purchased_num": {
          "type": "integer"
        },
        "shop_price": {
          "type": "scaled_float",
          "scaling_factor": 100
        },
        "city": {
          "type": "nested",
          "properties": {
            "city_id": {
              "type": "keyword"
            },
            "shop_price": {
              "type": "scaled_float",
              "scaling_factor": 100
            }
          }
        },
        "promotion": {
          "type": "nested",
          "properties": {
            "shop_price": {
              "type": "scaled_float",
              "scaling_factor": 100
            }
          }
        }
      }
    }
  }
}

三、测试数据

PUT  goods_detail_one_source_a/goods_detail_one_type/757
{
	"shop_price": "401000.00",
	"city": [
	{
	  "shop_price": "333333.00",
	  "city_id": null
	}
	],
	"goods_id": "757",
	"purchased_num": 7,
	"promotion": [
	{
	  "shop_price": null
	}
	]     
}

PUT  goods_detail_one_source_a/goods_detail_one_type/694
{
	"shop_price": "299999.00",
	"city": [
	{
	  "shop_price": "299999.00",
	  "city_id": null
	}
	],
	"goods_id": "694",
	"purchased_num": 2,
	"promotion": [
	{
	  "shop_price": "288888.00"
	}
	]
}



PUT goods_detail_one_source_a/goods_detail_one_type/1937
{
	"shop_price": "5433.00",
	"city": [
	{
	  "shop_price": "3333.00",
	  "city_id": "1111"
	}
	],
	"goods_id": "1937",
	"purchased_num": 15106,
	"promotion": [
	{
	  "shop_price": null
	}
	]
}

PUT goods_detail_one_source_a/goods_detail_one_type/119
{
	"shop_price": "490.00",
	"city": [
	{
	  "shop_price": "666.00",
	  "city_id": "2222"
	}
	],
	"goods_id": "119",
	"purchased_num": 8839,
	"promotion": [
	{
	  "shop_price": null
	}
	]
}

四、模拟需求一

4、1DSL语句

POST  goods_detail_one_source_a/goods_detail_one_type/_search
{
    "from": 0,
    "size": 10,
    "query": {
        "match_all": {}
    },
    "explain": false,
    "_source": {
        "includes": [
            "goods_id",
            "purchased_num",
            "shop_price",
            "city.city_id",
            "city.shop_price",
            "promotion.shop_price"
        ],
        "excludes": []
    },
    "sort": [
        {
            "_script": {
                "script": {
                    "source": "def cityId=params['_source']['city'][0].city_id;def cityShopPrice=params['_source']['city'][0].shop_price;if(Objects.isNull(cityId)){def promotionShopPrice=params['_source']['promotion'][0].shop_price;if(Objects.isNull(promotionShopPrice)){def shopPrice = doc['shop_price'].value;if(Objects.isNull(shopPrice)){shopPrice = 0;}return shopPrice;}else{return Double.parseDouble(promotionShopPrice);}}else{if(Objects.isNull(cityShopPrice)){return 0;}else{return Double.parseDouble(cityShopPrice);}}",
                    "lang": "painless"
                },
                "type": "number",
                "order": "desc"
            }
        }
    ]
}

4、2结果集

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": null,
    "hits": [
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "757",
        "_score": null,
        "_source": {
          "shop_price": "401000.00",
          "city": [
            {
              "shop_price": "333333.00",
              "city_id": null
            }
          ],
          "goods_id": "757",
          "purchased_num": 7,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "sort": [
          401000
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "694",
        "_score": null,
        "_source": {
          "shop_price": "299999.00",
          "city": [
            {
              "shop_price": "299999.00",
              "city_id": null
            }
          ],
          "goods_id": "694",
          "purchased_num": 2,
          "promotion": [
            {
              "shop_price": "288888.00"
            }
          ]
        },
        "sort": [
          288888
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "1937",
        "_score": null,
        "_source": {
          "shop_price": "5433.00",
          "city": [
            {
              "shop_price": "3333.00",
              "city_id": "1111"
            }
          ],
          "goods_id": "1937",
          "purchased_num": 15106,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "sort": [
          3333
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "119",
        "_score": null,
        "_source": {
          "shop_price": "490.00",
          "city": [
            {
              "shop_price": "666.00",
              "city_id": "2222"
            }
          ],
          "goods_id": "119",
          "purchased_num": 8839,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "sort": [
          666
        ]
      }
    ]
  }
}

4、3在java中的用法

#模拟script-painless
Script script = new Script(ScriptType.INLINE,"painless","DSL语句script中source字段的内容",Collections.EMPTY_MAP);
SortBuilder sortBuilder = SortBuilders.scriptSort(script, ScriptSortBuilder.ScriptSortType.NUMBER);
sortBuilder.order(SortOrder.DESC降序或SortOrder.ASC升序);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.sort(sortBuilder)
		.query(QueryBuilder).explain(false)
		.from(1).size(10)
		.fetchSource(过滤的字段,null);

#获取sort_shop_price排序后价格的值
searchResponse.getHits().forEach((hit) -> {
		//source中的原始字段
		Map<String, Object> sourceMap = hit.getSourceAsMap();
		//价格升降排序取值
		Object[] sortValues = hit.getSortValues();
		//获取sort_shop_price排序后价格的值
		Object objVal = sortValues[0];		
	}
);

五、模拟需求二

5、1 DSL语句

#这里要注意一点,如果要有返回结果集字段,那么必须声明要过滤的字段,不然最终只会展示sort_shop_price,而查询出来的条数只会以NULL的形式展示。(java同理)

POST  goods_detail_one_source_a/goods_detail_one_type/_search
{
    "from": 0,
    "size": 10,
    "query": {
        "match_all": {}
    },
    "explain": false,
    "_source": {
        "includes": [
            "goods_id",
            "purchased_num",
            "shop_price",
            "city.city_id",
            "city.shop_price",
            "promotion.shop_price"
        ],
        "excludes": []
    },
    "script_fields": {
        "sort_shop_price": {
            "script": {
                "source": "def cityId=params['_source']['city'][0].city_id;def cityShopPrice=params['_source']['city'][0].shop_price;if(Objects.isNull(cityId)){def promotionShopPrice=params['_source']['promotion'][0].shop_price;if(Objects.isNull(promotionShopPrice)){def shopPrice = doc['shop_price'].value;if(Objects.isNull(shopPrice)){shopPrice = '0';}return shopPrice;}else{return Double.parseDouble(promotionShopPrice);}}else{if(Objects.isNull(cityShopPrice)){cityShopPrice = '0';return cityShopPrice;}else{return cityShopPrice;}}",
                "lang": "painless"
            },
            "ignore_failure": false
        }
    },
    "sort": [
        {
            "purchased_num": {
                "order": "desc"
            }
        }
    ]
}

5、2结果集

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": null,
    "hits": [
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "1937",
        "_score": null,
        "_source": {
          "shop_price": "5433.00",
          "city": [
            {
              "shop_price": "3333.00",
              "city_id": "1111"
            }
          ],
          "goods_id": "1937",
          "purchased_num": 15106,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            "3333.00"
          ]
        },
        "sort": [
          15106
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "119",
        "_score": null,
        "_source": {
          "shop_price": "490.00",
          "city": [
            {
              "shop_price": "666.00",
              "city_id": "2222"
            }
          ],
          "goods_id": "119",
          "purchased_num": 8839,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            "666.00"
          ]
        },
        "sort": [
          8839
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "757",
        "_score": null,
        "_source": {
          "shop_price": "401000.00",
          "city": [
            {
              "shop_price": "333333.00",
              "city_id": null
            }
          ],
          "goods_id": "757",
          "purchased_num": 7,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            401000
          ]
        },
        "sort": [
          7
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "694",
        "_score": null,
        "_source": {
          "shop_price": "299999.00",
          "city": [
            {
              "shop_price": "299999.00",
              "city_id": null
            }
          ],
          "goods_id": "694",
          "purchased_num": 2,
          "promotion": [
            {
              "shop_price": "288888.00"
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            288888
          ]
        },
        "sort": [
          2
        ]
      }
    ]
  }
}

5、3在java中的用法

#模拟script-painless
#这里要注意一点,如果要有返回结果集字段,那么必须声明要过滤的字段,不然最终只会展示sort_shop_price,而查询出来的条数只会以NULL的形式展示。(DSL语句同理)
Script script = new Script(ScriptType.INLINE,"painless","DSL语句script中source字段的内容",Collections.EMPTY_MAP);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.scriptField("sort_shop_price自定义字段名称",script)
		.query(QueryBuilder).explain(false)
		.from(1).size(10)
		.sort("purchased_num", SortOrder.DESC)
		.fetchSource(过滤的字段,null);

#获取sort_shop_price排序后价格的值
searchResponse.getHits().forEach((hit) -> {
			//source中的原始字段
			Map<String, Object> sourceMap = hit.getSourceAsMap();
			//script声明field字段
			Map<String, DocumentField> filedMap = hit.getFields();
			//获取sort_shop_price排序后价格的值
			double shop_price_double = Double.parseDouble(String.valueOf(filedMap.get("sort_shop_price").getValues().get(0)));
		}
	);
}

六、知识点延伸

6、1关于排序的用法

在需求一和需求二中,可以发现二者的排序方式是不一样的,需求一是在”sort”中根据计算好的价格直接排序,并没有自定义返回字段,在结果集中多了”sort”;需求二中是把计算好的价格通过自定义字段声明到索引结果集来展示,最终是按照索引中原始的字段来排序,在结果集中多了”sort”,而且把自定义的字段”sort_shop_price”加入到了”fields”中来展示。

还需要注意的一点是,在需求二中查询,如果要返回结果集字段,那么必须声明要过滤的字段,不然最终只会展示sort_shop_price,而查询出来的条数只会以NULL的形式展示。

6、2关于painless的简单用法

参考“https://www.elastic.co/guide/en/elasticsearch/painless/6.1/index.html”即可。

如果要在painless中获取nested嵌套中字段的值(对应索引结构),那么用法例如:

“def cityShopPrice=params[‘_source’][‘city’][0].shop_price;”

如果要在painless中获取非nested嵌套中的字段的值(对应索引结构),那么用法例如:

def shopPrice = doc[‘shop_price’].value;

在模拟需求中,painless中使用的方法,比如“Objects.isNull(cityShopPrice))”和“Double.parseDouble(cityShopPrice)”,参考上述链接中的API部分,页面中描述的“static double parseDouble(String) (java 9)”,这里的意思是截止到java 9版本的环境都可用,并不是说只能在java 9版本环境中使用。

6、3关于获取字段值的其他发现

在“二、索引模拟结构”中,city的type类型是nested,现在新建索引,把“二、索引模拟结构”中的嵌套类型”city”和”promotion”中的’ “type”: “nested”,’去掉。

在下述的script脚本中,把source对应的值统一换成”return doc[‘city.city_id’].value;”。

6、3、1索引结构

#索引名称goods_detail_two_source_a

{
  "mappings": {
    "goods_detail_two_type":{
      "properties": {
        "goods_id": {
          "type": "keyword",
          "store": "true"
        },
        "purchased_num": {
          "type": "integer"
        },
        "shop_price": {
          "type": "scaled_float",
          "scaling_factor": 100
        },
        "city": {
          "properties": {
            "city_id": {
              "type": "keyword"
            },
            "shop_price": {
              "type": "scaled_float",
              "scaling_factor": 100
            }
          }
        },
        "promotion": {
          "properties": {
            "shop_price": {
              "type": "scaled_float",
              "scaling_factor": 100
            }
          }
        }
      }
    }
  }
}

6、3、2测试数据

PUT  goods_detail_two_source_a/goods_detail_two_type/757
{
	"shop_price": "401000.00",
	"city": [
	{
	  "shop_price": "333333.00",
	  "city_id": "333333"
	},
	{
	  "shop_price": "222222.00",
	  "city_id": "222222"
	}
	],
	"goods_id": "757",
	"purchased_num": 7,
	"promotion": [
	{
	  "shop_price": null
	}
	]     
}

PUT  goods_detail_two_source_a/goods_detail_two_type/694
{
	"shop_price": "299999.00",
	"city": [
	{
	  "shop_price": "299999.00",
	  "city_id": "299999"
	},
	{
	  "shop_price": "111111.00",
	  "city_id": "111111"
	}
	],
	"goods_id": "694",
	"purchased_num": 2,
	"promotion": [
	{
	  "shop_price": "288888.00"
	}
	]
}



PUT goods_detail_two_source_a/goods_detail_two_type/1937
{
	"shop_price": "5433.00",
	"city": [
	{
	  "shop_price": "3333.00",
	  "city_id": "3333"
	},
	{
	  "shop_price": "44444.00",
	  "city_id": "44444"
	}
	],
	"goods_id": "1937",
	"purchased_num": 15106,
	"promotion": [
	{
	  "shop_price": null
	}
	]
}

PUT goods_detail_two_source_a/goods_detail_two_type/119
{
	"shop_price": "490.00",
	"city": [
	{
	  "shop_price": "666.00",
	  "city_id": "666"
	},
	{
	  "shop_price": "5555.00",
	  "city_id": "5555"
	}
	],
	"goods_id": "119",
	"purchased_num": 8839,
	"promotion": [
	{
	  "shop_price": null
	}
	]
}

6、3、3在painless中获取city集合中的值

6、3、3、1goods_detail_two_source_a模拟需求一

6、3、3、1、1DSL语句

POST  goods_detail_two_source_a/goods_detail_two_type/_search
{
    "from": 0,
    "size": 10,
    "query": {
        "match_all": {}
    },
    "explain": false,
    "_source": {
        "includes": [
            "goods_id",
            "purchased_num",
            "shop_price",
            "city.city_id",
            "city.shop_price",
            "promotion.shop_price"
        ],
        "excludes": []
    },
    "sort": [
        {
            "_script": {
                "script": {
                    "source": "return doc['city.shop_price'][1];",
                    "lang": "painless"
                },
                "type": "number",
                "order": "desc"
            }
        }
    ]
}

6、3、3、1、2结果集

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": null,
    "hits": [
      {
        "_index": "goods_detail_two_source_a",
        "_type": "goods_detail_two_type",
        "_id": "757",
        "_score": null,
        "_source": {
          "shop_price": "401000.00",
          "city": [
            {
              "shop_price": "333333.00",
              "city_id": "333333"
            },
            {
              "shop_price": "222222.00",
              "city_id": "222222"
            }
          ],
          "goods_id": "757",
          "purchased_num": 7,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "sort": [
          333333
        ]
      },
      {
        "_index": "goods_detail_two_source_a",
        "_type": "goods_detail_two_type",
        "_id": "694",
        "_score": null,
        "_source": {
          "shop_price": "299999.00",
          "city": [
            {
              "shop_price": "299999.00",
              "city_id": "299999"
            },
            {
              "shop_price": "111111.00",
              "city_id": "111111"
            }
          ],
          "goods_id": "694",
          "purchased_num": 2,
          "promotion": [
            {
              "shop_price": "288888.00"
            }
          ]
        },
        "sort": [
          299999
        ]
      },
      {
        "_index": "goods_detail_two_source_a",
        "_type": "goods_detail_two_type",
        "_id": "1937",
        "_score": null,
        "_source": {
          "shop_price": "5433.00",
          "city": [
            {
              "shop_price": "3333.00",
              "city_id": "3333"
            },
            {
              "shop_price": "44444.00",
              "city_id": "44444"
            }
          ],
          "goods_id": "1937",
          "purchased_num": 15106,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "sort": [
          44444
        ]
      },
      {
        "_index": "goods_detail_two_source_a",
        "_type": "goods_detail_two_type",
        "_id": "119",
        "_score": null,
        "_source": {
          "shop_price": "490.00",
          "city": [
            {
              "shop_price": "666.00",
              "city_id": "666"
            },
            {
              "shop_price": "5555.00",
              "city_id": "5555"
            }
          ],
          "goods_id": "119",
          "purchased_num": 8839,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "sort": [
          5555
        ]
      }
    ]
  }
}

6、3、3、2goods_detail_two_source_a模拟需求二

6、3、3、2、1DSL语句

POST  goods_detail_two_source_a/goods_detail_two_type/_search
{
    "from": 0,
    "size": 10,
    "query": {
        "match_all": {}
    },
    "explain": false,
    "_source": {
        "includes": [
            "goods_id",
            "purchased_num",
            "shop_price",
            "city.city_id",
            "city.shop_price",
            "promotion.shop_price"
        ],
        "excludes": []
    },
    "script_fields": {
        "sort_shop_price": {
            "script": {
                "source": "return doc['city.shop_price'][1];",
                "lang": "painless"
            },
            "ignore_failure": false
        }
    },
    "sort": [
        {
            "purchased_num": {
                "order": "desc"
            }
        }
    ]
}

6、3、3、2、2结果集

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": null,
    "hits": [
      {
        "_index": "goods_detail_two_source_a",
        "_type": "goods_detail_two_type",
        "_id": "1937",
        "_score": null,
        "_source": {
          "shop_price": "5433.00",
          "city": [
            {
              "shop_price": "3333.00",
              "city_id": "3333"
            },
            {
              "shop_price": "44444.00",
              "city_id": "44444"
            }
          ],
          "goods_id": "1937",
          "purchased_num": 15106,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            44444
          ]
        },
        "sort": [
          15106
        ]
      },
      {
        "_index": "goods_detail_two_source_a",
        "_type": "goods_detail_two_type",
        "_id": "119",
        "_score": null,
        "_source": {
          "shop_price": "490.00",
          "city": [
            {
              "shop_price": "666.00",
              "city_id": "666"
            },
            {
              "shop_price": "5555.00",
              "city_id": "5555"
            }
          ],
          "goods_id": "119",
          "purchased_num": 8839,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            5555
          ]
        },
        "sort": [
          8839
        ]
      },
      {
        "_index": "goods_detail_two_source_a",
        "_type": "goods_detail_two_type",
        "_id": "757",
        "_score": null,
        "_source": {
          "shop_price": "401000.00",
          "city": [
            {
              "shop_price": "333333.00",
              "city_id": "333333"
            },
            {
              "shop_price": "222222.00",
              "city_id": "222222"
            }
          ],
          "goods_id": "757",
          "purchased_num": 7,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            333333
          ]
        },
        "sort": [
          7
        ]
      },
      {
        "_index": "goods_detail_two_source_a",
        "_type": "goods_detail_two_type",
        "_id": "694",
        "_score": null,
        "_source": {
          "shop_price": "299999.00",
          "city": [
            {
              "shop_price": "299999.00",
              "city_id": "299999"
            },
            {
              "shop_price": "111111.00",
              "city_id": "111111"
            }
          ],
          "goods_id": "694",
          "purchased_num": 2,
          "promotion": [
            {
              "shop_price": "288888.00"
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            299999
          ]
        },
        "sort": [
          2
        ]
      }
    ]
  }
}

6、3、3、3goods_detail_one_source_a模拟需求一

6、3、3、3、1DSL语句

POST  goods_detail_one_source_a/goods_detail_one_type/_search
{
    "from": 0,
    "size": 10,
    "query": {
        "match_all": {}
    },
    "explain": false,
    "_source": {
        "includes": [
            "goods_id",
            "purchased_num",
            "shop_price",
            "city.city_id",
            "city.shop_price",
            "promotion.shop_price"
        ],
        "excludes": []
    },
    "sort": [
        {
            "_script": {
                "script": {
                    "source": "return doc['city.shop_price'].value;",
                    "lang": "painless"
                },
                "type": "number",
                "order": "desc"
            }
        }
    ]
}

6、3、3、3、2结果集

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": null,
    "hits": [
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "119",
        "_score": null,
        "_source": {
          "shop_price": "490.00",
          "city": [
            {
              "shop_price": "666.00",
              "city_id": "2222"
            }
          ],
          "goods_id": "119",
          "purchased_num": 8839,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "sort": [
          0
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "694",
        "_score": null,
        "_source": {
          "shop_price": "299999.00",
          "city": [
            {
              "shop_price": "299999.00",
              "city_id": null
            }
          ],
          "goods_id": "694",
          "purchased_num": 2,
          "promotion": [
            {
              "shop_price": "288888.00"
            }
          ]
        },
        "sort": [
          0
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "757",
        "_score": null,
        "_source": {
          "shop_price": "401000.00",
          "city": [
            {
              "shop_price": "333333.00",
              "city_id": null
            }
          ],
          "goods_id": "757",
          "purchased_num": 7,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "sort": [
          0
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "1937",
        "_score": null,
        "_source": {
          "shop_price": "5433.00",
          "city": [
            {
              "shop_price": "3333.00",
              "city_id": "1111"
            }
          ],
          "goods_id": "1937",
          "purchased_num": 15106,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "sort": [
          0
        ]
      }
    ]
  }
}

6、3、3、4goods_detail_one_source_a模拟需求二

6、3、3、4、1DSL语句

POST  goods_detail_one_source_a/goods_detail_one_type/_search
{
    "from": 0,
    "size": 10,
    "query": {
        "match_all": {}
    },
    "explain": false,
    "_source": {
        "includes": [
            "goods_id",
            "purchased_num",
            "shop_price",
            "city.city_id",
            "city.shop_price",
            "promotion.shop_price"
        ],
        "excludes": []
    },
    "script_fields": {
        "sort_shop_price": {
            "script": {
                "source": "return doc['city.shop_price'].value;",
                "lang": "painless"
            },
            "ignore_failure": false
        }
    },
    "sort": [
        {
            "purchased_num": {
                "order": "desc"
            }
        }
    ]
}

6、3、3、4、2结果集

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": null,
    "hits": [
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "1937",
        "_score": null,
        "_source": {
          "shop_price": "5433.00",
          "city": [
            {
              "shop_price": "3333.00",
              "city_id": "1111"
            }
          ],
          "goods_id": "1937",
          "purchased_num": 15106,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            0
          ]
        },
        "sort": [
          15106
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "119",
        "_score": null,
        "_source": {
          "shop_price": "490.00",
          "city": [
            {
              "shop_price": "666.00",
              "city_id": "2222"
            }
          ],
          "goods_id": "119",
          "purchased_num": 8839,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            0
          ]
        },
        "sort": [
          8839
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "757",
        "_score": null,
        "_source": {
          "shop_price": "401000.00",
          "city": [
            {
              "shop_price": "333333.00",
              "city_id": null
            }
          ],
          "goods_id": "757",
          "purchased_num": 7,
          "promotion": [
            {
              "shop_price": null
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            0
          ]
        },
        "sort": [
          7
        ]
      },
      {
        "_index": "goods_detail_one_source_a",
        "_type": "goods_detail_one_type",
        "_id": "694",
        "_score": null,
        "_source": {
          "shop_price": "299999.00",
          "city": [
            {
              "shop_price": "299999.00",
              "city_id": null
            }
          ],
          "goods_id": "694",
          "purchased_num": 2,
          "promotion": [
            {
              "shop_price": "288888.00"
            }
          ]
        },
        "fields": {
          "sort_shop_price": [
            0
          ]
        },
        "sort": [
          2
        ]
      }
    ]
  }
}

6、3、4结果说明

在索引“goods_detail_one_source_a”中发现,不可以正确获取city集合中shop_price的值,虽然有字段展示,但是显示的值是0。

在索引“goods_detail_two_source_a”中发现,可以直接获取city集合中shop_price的值。

在索引“goods_detail_two_source_a”中,去掉索引结构”city”和”promotion”中的’ “type”: “nested”,’,数据可以以索引“goods_detail_one_source_a”中的形式录入,个人理解这样导致”city”和”promotion”是以普通集合的形式存在的,而不是嵌套对象。

由于这里的city是模拟的不同城市不同价格的业务,且用户在登录APP中只能获取一个城市的一个价格,这里还是要以嵌套格式创建数据,而且并不能以下标的形式获取到准确城市的价格值,所以不同的索引字段格式要适配不同的业务需求。


标题:关于es-painless的基本用法、嵌套字段处理及排序
作者:yazong
地址:https://blog.llyweb.com/articles/2019/03/29/1578151982700.html