Сортировка terms по результатам поиска


(Pashkevich Aleksandr) #1

Здравствуйте.
Я делаю запрос на получение terms, и он сортирует по количеству встречающихся в базе. А мне необходима сортировка по результатам поиска.

   "query": {
		"bool" : {
			"must" : {
				"query_string" : {
					"query" : "бампер передний huyndai"
							}
						}
					}
				},

Т.е. мне необходима группировка по определённому полю как в MySQL, без сортировки по количеству встречающихся terms.
Фактически этот запрос выполняет всё нужное мне, кроме сортировки по результатам поиска.
Так же при помощи aggs я подтягиваю для terms нужные мне поля для выгрузки. Возможно есть какой-нибудь простой вариант?

"aggs":{
					"products":{
					  "terms": {
						"field": "pr_article_search",
						"size": 10
					  },
					  "aggs": {
						  "new_price" : {
							"filter" : { "term": { "pr_is_new": 1 } },
							"aggs" : {
								"max_price" : { "max" : { "field" : "pr_price_calc" } },
								"min_price" : { "min" : { "field" : "pr_price_calc" } }
							}
						},
						"old_price" : {
							"filter" : { "term": { "pr_is_new": 0 } },
							"aggs" : {
								"max_price" : { "max" : { "field" : "pr_price_calc" } },
								"min_price" : { "min" : { "field" : "pr_price_calc" } }
							}
						},
					  "aggs": {
						"tops": {
						  "top_hits": {
							"size": 1
						  }
						}
					  }
					}
				  }

(Igor Motov) #2

Это https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-bucket-terms-aggregation.html#search-aggregations-bucket-terms-aggregation-order?


(Pashkevich Aleksandr) #3

Нет, тут сортировка термов, по тому что встречается в aggregations, а мне нужно на уровень выше по hits так называемым. Я пробовал делать сортировку по hits, но выдавало ошибку.
Ниже полный запрос который я шлю. Если приводить пример из mysql, то я хочу что-то типа

SELECT * FROM table GROUP BY pr_article_search

Только без сортировки по количеству встречающихся pr_article_search.
Результат выполнения этого запроса вот здесь можно посмотреть И там первый найденный pr_article_search это AMDSA15R, а в terms первый это 4431008C00

{
"query": {
	"bool" : {
		"must" : {
			"query_string" : {
					"query" : "фара"
							}
						}
					}
				},
						
  "aggs":{
	"products":{
		 "terms": {
			"field": "pr_article_search",
				"size": 10
			  },
 	 	 	 "aggs": {
				 "new_price" : {
					"filter" : { "term": { "pr_is_new": 1 } },
						"aggs" : {
								"max_price" : { "max" : { "field" : "pr_price_calc" } },
								"min_price" : { "min" : { "field" : "pr_price_calc" } }
							}
						},
						"old_price" : {
							"filter" : { "term": { "pr_is_new": 0 } },
							"aggs" : {
								"max_price" : { "max" : { "field" : "pr_price_calc" } },
								"min_price" : { "min" : { "field" : "pr_price_calc" } }
							}
						},
						"tops": {
						  "top_hits": {
							"size": 1
						  }
						}
					  }
					}
				  }
			
		}

(Igor Motov) #4

Я не понимаю, что вы хотите.


(Pashkevich Aleksandr) #5

Для моего запроса поиска выдаёт вот такие результаты.

В этом же запросе если я получаю terms по полю pr_article_search то вот такой порядок сортировки.

А мне нужно, что бы сортировка terms была в том же порядке что и у результатов поиска.

Условно говоря. Я делаю поиск по каком-либо слову/предложению. Получаю результаты поиска. И для каждого результата мне нужно получить сколько у меня ещё встречается записей у которых одинаковое pr_article_search. Но при этом что бы больше не повторялись результаты.

На живом примере. Предположим, что у меня есть вот такие записи

{"name": "John", "pr_article_search": 1},
{"name": "Mary", "pr_article_search": 2},
{"name": "Nick", "pr_article_search": 1},
{"name": "Bob", "pr_article_search": 3},
{"name": "Kenny", "pr_article_search": 1}

Результат поиска по фразе вернёт их вот в таком порядке

{"name": "Bob", "pr_article_search": 3},
{"name": "John", "pr_article_search": 1},
{"name": "Mary", "pr_article_search": 2},
{"name": "Kenny", "pr_article_search": 1}

И на выходе я хочу получить, что

 [0] => Array
                      (
                        [key] => 3
                        [name]=>Bob
                        [doc_count] => 1
                      )
[1] => Array
                       (
                        [key] => 1
                        [name]=>John
                        [doc_count] => 2
                        )

[2] => Array
                       (
                        [key] => 2
                        [name]=>Mary
                        [doc_count] => 1
                       )

(Igor Motov) #6

Я бы в два запроса это сделал. В первом - получаем результаты, потом для каждого результата из первого запроса, формируем filter aggs во втором запросе с size: 0.

Дело в том, что поиск выполняется в 2 этапа. На первом этапе мы только ищем, и сортируем, на втором - запрашиваем результаты полученные в результате сортировки. Все запросы агрегации выполняются во время 1-го этапа. То есть, когда агрегация происходит, мы еще не знаем, как результаты будут отсортированы. Так что единственный способ получить все за один запрос - это запросить абсолютно все термины и потом выкинуть то, что не вошло в 10 топ результатов.


(Pashkevich Aleksandr) #7

Спасибо. Значит буду делать в два запроса.
Я надеялся, что можно как-то в один запрос сделать.


(system) #8

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.