elasticsearch возвращает совпадения, найденные в агрегации - PullRequest
1 голос
/ 04 августа 2020

Я пытаюсь получить строки из моей базы данных с уникальным полем sku.

У меня есть рабочий запрос, который правильно подсчитывает это число, мой запрос:

GET _search
{
"size": 0,
"aggs": {
  "unique_products":{  
    "cardinality":{
      "field":"sku.keyword"
    }  
  }
},
"query": {
  "bool": {
    "must": [
      {
        "query_string": {
          "query": "(merch1: 'Dog') AND ((store_name: 'walmart')) AND product_gap: 'yes'"
        }
      },
      {
        "range": {
          "capture_date": {
            "format": "date",
            "gte": "2020-05-13",
            "lte": "2020-08-03"
          }
        }
      } 
    ]
  }
}

}

Возвращает этот результат:

{
  "took" : 129,
  "timed_out" : false,
  "_shards" : {
    "total" : 514,
    "successful" : 514,
    "skipped" : 98,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 150,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "unique_products" : {
      "value" : 38
    }
  }
}

Что правильно сообщает количество unique_products как 38.

Я пытаюсь отредактировать этот запрос, чтобы он действительно возвращал все 38 уникальных продуктов, но я не уверен как, я начал с попытки вернуть наивысший результат из результата agg:

GET _search
{
"size": 0,
"aggs": {
  "unique_products":{  
    "cardinality":{
      "field":"sku.keyword"
    }  
  },
  "top_hits": {
    "size": 1,
    "_source": {
      "include": [
        "sku", "source_store"
      ]
    }
  }
},
"query": {
  "bool": {
    "must": [
      {
        "query_string": {
          "query": "(merch1: 'Dog') AND ((store_name: 'walmart')) AND product_gap: 'yes'"
        }
      },
      {
        "range": {
          "capture_date": {
            "format": "date",
            "gte": "2020-05-13",
            "lte": "2020-08-03"
          }
        }
      } 
    ]
  }
}

}

Но в моем результате появилась ошибка:

{
  "error": {
    "root_cause": [
      {
        "type": "parsing_exception",
        "reason": "Expected [START_OBJECT] under [size], but got a [VALUE_NUMBER] in [top_hits]",
        "line": 10,
        "col": 13
      }
    ],
    "type": "parsing_exception",
    "reason": "Expected [START_OBJECT] under [size], but got a [VALUE_NUMBER] in [top_hits]",
    "line": 10,
    "col": 13
  },
  "status": 400
}

Я все еще лучше всего схожим по мощности ставка на возврат всех 38 уникальных товаров? спасибо

1 Ответ

0 голосов
/ 04 августа 2020

Хотя агрегирование мощности дает уникальное количество, оно не может принимать подаггеры. Другими словами, top_hits нельзя использовать здесь напрямую.

Подход был правильным, но вы можете сначала разделить sku s, а затем получить базовые документы, используя top_hits:

{
  "size": 0,
  "aggs": {
    "unique_products": {
      "cardinality": {
        "field": "sku.keyword"
      }
    },
    "terms_agg": {
      "terms": {
        "field": "sku.keyword",
        "size": 100
      },
      "aggs": {
        "top_hits_agg": {
          "top_hits": {
            "size": 1,
            "_source": {
              "include": [
                "sku",
                "source_store"
              ]
            }
          }
        }
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "(merch1: 'Dog') AND ((store_name: 'walmart')) AND product_gap: 'yes'"
          }
        },
        {
          "range": {
            "capture_date": {
              "format": "date",
              "gte": "2020-05-13",
              "lte": "2020-08-03"
            }
          }
        }
      ]
    }
  }
}

FYI Причина, по которой ваш запрос выдал исключение, заключается в том, что top_hits является агг типом и, как и unique_products, у него отсутствует собственное имя.

...