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

**URL:** <https://discuss.elastic.co/t/terms/74712>\
**Category:** Вопросы на русском языке\
**Created:** [February 10, 2017, 8:35pm UTC](https://discuss.elastic.co/t/terms/74712 "2017-02-10T20:35:59Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pashkevich\_Aleksandr](https://avatars.discourse-cdn.com/v4/letter/p/a4c791/32.png) [@Pashkevich\_Aleksandr](https://discuss.elastic.co/u/Pashkevich_Aleksandr)\
**Post date:** [February 10, 2017, 8:35pm UTC](https://discuss.elastic.co/t/terms/74712/1 "2017-02-10T20:35:59Z")

</div>

Здравствуйте.  
Я делаю запрос на получение 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
						  }
						}
					  }
					}
				  }
```

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [February 10, 2017, 9:48pm UTC](https://discuss.elastic.co/t/terms/74712/2 "2017-02-10T21:48:08Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Pashkevich\_Aleksandr](https://avatars.discourse-cdn.com/v4/letter/p/a4c791/32.png) [@Pashkevich\_Aleksandr](https://discuss.elastic.co/u/Pashkevich_Aleksandr)\
**Post date:** [February 10, 2017, 10:18pm UTC](https://discuss.elastic.co/t/terms/74712/3 "2017-02-10T22:18:31Z")

</div>

Нет, тут сортировка термов, по тому что встречается в 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
						  }
						}
					  }
					}
				  }
			
		}

```

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [February 11, 2017, 12:06am UTC](https://discuss.elastic.co/t/terms/74712/4 "2017-02-11T00:06:59Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Pashkevich\_Aleksandr](https://avatars.discourse-cdn.com/v4/letter/p/a4c791/32.png) [@Pashkevich\_Aleksandr](https://discuss.elastic.co/u/Pashkevich_Aleksandr)\
**Post date:** [February 11, 2017, 12:29am UTC](https://discuss.elastic.co/t/terms/74712/5 "2017-02-11T00:29:53Z")

</div>

Для моего запроса поиска выдаёт вот такие результаты.  
[![](http://image.prntscr.com/image/890f35290f0a415880148283c29afddd.png) ](http://image.prntscr.com/image/890f35290f0a415880148283c29afddd.png)  
В этом же запросе если я получаю terms по полю pr\_article\_search то вот такой порядок сортировки.  
[![](http://image.prntscr.com/image/a73b39eb51ba4622a92e2f485809832c.png) ](http://image.prntscr.com/image/a73b39eb51ba4622a92e2f485809832c.png)  
А мне нужно, что бы сортировка 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
                       )
```

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [February 11, 2017, 2:44am UTC](https://discuss.elastic.co/t/terms/74712/6 "2017-02-11T02:44:04Z")

</div>

Я бы в два запроса это сделал. В первом - получаем результаты, потом для каждого результата из первого запроса, формируем [filter aggs](https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-bucket-filter-aggregation.html) во втором запросе с size: 0.

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

---

<div class="post-metadata">

**Author:** ![Pashkevich\_Aleksandr](https://avatars.discourse-cdn.com/v4/letter/p/a4c791/32.png) [@Pashkevich\_Aleksandr](https://discuss.elastic.co/u/Pashkevich_Aleksandr)\
**Post date:** [February 11, 2017, 6:44am UTC](https://discuss.elastic.co/t/terms/74712/7 "2017-02-11T06:44:59Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [March 11, 2017, 6:45am UTC](https://discuss.elastic.co/t/terms/74712/8 "2017-03-11T06:45:05Z")

</div>

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