Эластичная сортировка по весу - PullRequest
0 голосов
/ 23 октября 2019

Я сохранил документы, которые содержат статус свойства. Я хотел бы отсортировать документы по приоритету статуса (не по алфавиту). Я следовал за предыдущими ответами и составил следующую функцию, которая все еще не работает должным образом;документы отсортированы по статусным именам (в алфавитном порядке):

function getESSortingByStatusQuery(query, order) {
        let statusOrder = ['BLUE', 'RED', 'BLACK', 'YELLOW', 'GREEN'];
        if(order == 'desc'){
            statusOrder.reverse();
        }
        const functions = statusOrder.map((item) => {
            const idx = statusOrder.indexOf(item);
            return {filter: {match: {statusColor: item}},
                weight: (idx + 1) * 50}
        });
        const queryModified = {
            "function_score": {
                "query": {"match_all": {}}, // this is for testing purposes and should be replaced with original query
                "boost": "5",
                "functions": functions,
                "score_mode": "multiply",
                "boost_mode": "replace"
            }
        }
        return queryModified;
    }

Я был бы благодарен, если бы кто-нибудь предложил способ сортировки элементов в соответствии с предопределенным приоритетом свойства (в данном случае статуса).

Ответы [ 2 ]

1 голос
/ 24 октября 2019
Here's the code sample of sorting result. I think this will helps you. If you don't want to get entire documents as result you can filter results using includes. 

GET testindex/_search
{
  "_source": {
"includes": [
  "filed1"
]
},
  "aggs": {
    "emp_figures": {
      "terms": {
        "field": "status"
      }
    }
}
}

This is the sample result you should retrieve 
{
  "took": 11,
  "timed_out": false,
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "hits": {
    "total": 84968,
    "max_score": 1,
    "hits": [
      {
        "_index": "test",
        "_type": "type",
        "_id": "0001",
        "_score": 1,
        "_source": {
          "filed1": "color1,
          }
        },
         {
        "_index": "test",
        "_type": "type",
        "_id": "0002",
        "_score": 1,
        "_source": {
          "filed1": "color2,
          }
        }
      }
    }
}
1 голос
/ 23 октября 2019

Ниже приведен пример пользовательского сценария сортировки , который, я думаю, является тем, что вы ищете. Я добавил образец сопоставления, документы, запрос и ответ, как он выглядит.

Отображение:

PUT color_index
{
  "mappings": {
    "properties": {
      "color":{
        "type": "keyword"
      },
      "product":{
        "type": "text"
      }
    }
  }
}

Образцы документов:

POST color_index/_doc/1
{
  "color": "BLUE",
  "product": "adidas and nike"
}

POST color_index/_doc/2
{
  "color": "GREEN",
  "product": "adidas and nike and puma"
}

POST color_index/_doc/3
{
  "color": "GREEN",
  "product": "adidas and nike"
}

POST color_index/_doc/4
{
  "color": "RED",
  "product": "nike"
}

POST color_index/_doc/5
{
  "color": "RED",
  "product": "adidas and nike"
}

Запрос:

POST color_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "default_field": "*",
            "query": "adidas OR nike"
          }
        }
      ]
    }
  },
  "sort": [
    { "_score": { "order": "desc"} },          <---- First sort by score
    { "_script": {                             <---- Second sort by Colors
            "type": "number",
            "script": {
                "lang": "painless",
                "source": "if(params.scores.containsKey(doc['color'].value)) { return params.scores[doc['color'].value];} return 100000;",
                "params": {
                    "scores": {
                        "BLUE": 0,
                        "RED": 1,
                        "BLACK": 2,
                        "YELLOW": 3,
                        "GREEN": 4
                    }
                }
            },
            "order": "asc"
        }

    }
  ]
}

Сначала он вернет документы, отсортированные по его оценке,и тогда он применил бы вторую логику сортировки к этому результату.

Для второй сортировки, то есть с использованием сортировки сценариев, обратите внимание, как я добавил числовые значения к цветам в разделе scores. Вам нужно будет соответственно построить свой запрос.

Логика того, как он работает, находится в разделе source, который, я считаю, самоочевиден, где я использовал doc ['color']. Value так как это было моим полем, к которому я применяю собственную логику сортировки.

Ответ:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "color_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.5159407,
        "_source" : {
          "color" : "BLUE",
          "product" : "adidas and nike"
        },
        "sort" : [
          0.5159407,                     <--- This value is score(desc by nature)
          0.0                            <--- This value comes from script sort as its BLUE and I've used value 0 in the script which is in 'asc' order
        ]
      },
      {
        "_index" : "color_index",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 0.5159407,
        "_source" : {
          "color" : "RED",
          "product" : "adidas and nike"
        },
        "sort" : [
          0.5159407,
          1.0
        ]
      },
      {
        "_index" : "color_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.5159407,
        "_source" : {
          "color" : "GREEN",
          "product" : "adidas and nike"
        },
        "sort" : [
          0.5159407,
          4.0
        ]
      },
      {
        "_index" : "color_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.40538198,
        "_source" : {
          "color" : "GREEN",
          "product" : "adidas and nike and puma"
        },
        "sort" : [
          0.40538198,
          4.0
        ]
      },
      {
        "_index" : "color_index",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 0.10189847,
        "_source" : {
          "color" : "RED",
          "product" : "nike"
        },
        "sort" : [
          0.10189847,
          1.0
        ]
      }
    ]
  }
}

Обратите внимание на первые три документа, он имеет точное значение product, но отличается color, и вы можете видеть, что они сгруппированы вместе, как мы впервые отсортировали по_score затем мы сортируем это по color

Дайте мне знать, если это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...