elasticsearch - 源过滤 ElasticSearch 中的对象数组
问题描述
这是 ElasticSearch 中的一个文档
"CompanyId": 5733,
"PartNumber": "W8S038",
"Name_en": "#8 Washer, M4 Compatible, Stainless Steel, Pack of 100",
"ProductId": 90023,
"CompanyName": "Washers Ltd",
"Prices": [
{
"BuyerId": 308,
"Price": 2.42
}
,
{
"BuyerId": 406,
"Price": 2.22
}
]
}
显然,我们不能让买家 308 知道买家 406 正在获得更好的价格。因此,当买家 308 正在搜索时,我需要删除其他买家的所有价格。
我想通过使用源过滤来做到这一点。但是怎么办?!
(我可以使用 排除Prices
并添加所需的价格script_field
。但是,这意味着价格不是源文档的一部分,因此 ReactiveSearch 看不到它,因此无法对其进行排序。)
更新:这是由 ReactiveSearch 生成的查询,我需要在其中附加价格限制:
"query":{
"bool":{
"must":[
{
"bool":{
"must":[
{
"bool":{
"must":[
{
"bool":{
"should":[
{
"multi_match":{
"query":"m4 washer",
"fields":[
"Name_en"
],
"type":"cross_fields",
"operator":"and"
}
},
{
"multi_match":{
"query":"m4 washer",
"fields":[
"Name_en"
],
"type":"phrase_prefix",
"operator":"and"
}
}
],
"minimum_should_match":"1"
}
}
]
}
}
]
}
}
],
"filter": [
{
"nested": {
"path": "Prices",
"query": {
"term": {
"Prices.CompanyId": 1474
}
},
"inner_hits": {}
}
}
]
}
},
"size":10,
"aggs":{
"CompanyName.raw":{
"terms":{
"field":"CompanyName.raw",
"size":1000,
"order":{
"_count":"desc"
}
}
}
},
"_source":{
"excludes":[
"PurchasingViews",
"ContractFilters",
"SearchField*",
"Keywords*",
"Menus*"
]
},
"from":0,
"sort":[
{
"Name_en.raw":{
"order":"asc"
}
}
],
"script_fields":{
"price":{
"script":{
"lang":"painless",
"inline":"if(params['_source']['Prices'] != null){for(p in params['_source']['Prices']){ if(p.CompanyId == 1474) return p.Price; }} return null;"
}
}
}
}
(这bool, must, bool, must, bool, must, bool, should
似乎相当愚蠢?)
解决方案
您需要使用下面的嵌套inner_hits
功能。
{
"_source": [
"CompanyId", "PartNumber", "Name_en", "ProductId", "CompanyName"
],
"query": {
"bool": {
"filter": [
{
"nested": {
"path": "Prices",
"query": {
"term": {
"Prices.BuyerId": 308
}
},
"inner_hits": {}
}
}
]
}
}
}
在输出中,您将得到您所期望的,即所有根级字段和给定买家的匹配价格。
更新:
以下是我将如何重写您的查询:
{
"query": {
"bool": {
"minimum_should_match": "1",
"should": [
{
"multi_match": {
"query": "m4 washer",
"fields": [
"Name_en"
],
"type": "cross_fields",
"operator": "and"
}
},
{
"multi_match": {
"query": "m4 washer",
"fields": [
"Name_en"
],
"type": "phrase_prefix",
"operator": "and"
}
}
],
"filter": [
{
"nested": {
"path": "Prices",
"query": {
"term": {
"Prices.CompanyId": 1474
}
},
"inner_hits": {}
}
}
]
}
},
"size": 10,
"aggs": {
"CompanyName.raw": {
"terms": {
"field": "CompanyName.raw",
"size": 1000,
"order": {
"_count": "desc"
}
}
}
},
"_source": {
"excludes": [
"PurchasingViews",
"ContractFilters",
"SearchField*",
"Keywords*",
"Menus*",
"Prices"
]
},
"from": 0,
"sort": [
{
"Name_en.raw": {
"order": "asc"
}
}
],
"script_fields": {
"price": {
"script": {
"lang": "painless",
"inline": "if(params['_source']['Prices'] != null){for(p in params['_source']['Prices']){ if(p.CompanyId == 1474) return p.Price; }} return null;"
}
}
}
}
推荐阅读
- angularjs - Angularjs UI路由器解析不起作用
- excel - 如果该行包含数字列表中的任何数字,如何将一行从一张纸复制到另一张纸?
- javascript - 如何提高 requestAnimationFrame 性能?
- sql - 具有特定状态的不同日子 - SQL Oracle
- sql - 数据库链接 - 无效的用户名/密码
- java - Vaadin-Maven-Plugin 找不到目标
- python - 预测错误 - Keras 功能 API
- realm - 将 Realm 与多租户 Postgresql 模式一起使用
- javascript - 如何将 div 导出为 PDF?
- c# - JSON 模式到 C# 类