Применение фильтра для исключения определенного числового значения в поле вложенного объекта с помощью эластичного поиска

Я пытаюсь вычислить агрегированное среднее значение поля в моей базе данных с помощью elasticsearch. У меня нет проблем с вычислением значения av без фильтрации:

{
    "query": {
        "match_all":{}
    },
    "size": 0,
    "aggs": {
        "avg_quantity": {
            "avg": {
                "field": "license_offer.unit_price"
            }
        }
    }   
}

Однако мне нужно исключить из документов агрегирования, у которых license_offer.unit_price равен 0 (licence_offer - это вложенный объект в лицензии).

Я пробовал разные вещи, это моя последняя попытка:

{
    "size": 0,
    "query": {
        "constant_score": {
            "filter": {
                "license_offer.unit_price": {
                        "gte": 0
                }
            }
        }
    },
    "aggs": {
        "quantity_stats": {
            "stats": {
                "field": "license_offer.unit_price"
            }
        }
    }

}

но я получаю сообщение об ошибке:

 "type": "parsing_exception",
        "reason": "no [query] registered for [license_offer.unit_price]",

Как применить фильтр для исключения определенного числового значения в поле вложенного объекта с помощью эластичного поиска?


person David Geismar    schedule 29.11.2016    source источник


Ответы (1)


Ваш запрос неверен, вам просто не хватает ключевого слова range:

{
    "size": 0,
    "query": {
        "constant_score": {
            "filter": {
                "range": {                           <--- add this
                     "license_offer.unit_price": {
                        "gte": 0
                     }
                }
            }
        }
    },
    "aggs": {
        "quantity_stats": {
            "stats": {
                "field": "license_offer.unit_price"
            }
        }
    }

}

Вы также можете переместить фильтр внутри агрегированной части:

{
  "size": 0,
  "aggs": {
    "only_positive": {
      "filter": {
        "range": {
          "license_offer.unit_price": {
            "gt": 0
          }
        }
      },
      "aggs": {
        "quantity_stats": {
          "stats": {
            "field": "license_offer.unit_price"
          }
        }
      }
    }
  }
}
person Val    schedule 29.11.2016
comment
спасибо @val, не могли бы вы показать, как бы вы это сделали, специально исключив значение 0? - person David Geismar; 29.11.2016
comment
Использовать gt вместо gte? - person Val; 29.11.2016
comment
Да, я только что это сделал, но есть ли способ сделать это без использования логики диапазона, а с логикой исключения / фильтрации (что-то вроде не 0) - person David Geismar; 29.11.2016
comment
Да, вы можете переместить фильтр внутри агрегатной части. Смотрите мой обновленный ответ - person Val; 29.11.2016