1. ホーム
  2. sorting

[解決済み] Elasticsearchがフィルタにないフィールドの値で注文する。

2022-01-31 18:24:03

質問

フィールドがリクエストのクエリの一部でない場合、フィールド値に従って結果アイテムを並べるクエリを作るのに、誰か助けてくれませんか?私はクエリを持っています。

{
    "_source": [
        "ico",
        "name",
        "city",
        "status"
    ],
    "sort": {
        "_score": "desc",
        "status": "asc"
    },
    "size": 20,
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "normalized": {
                            "query": "idona",
                            "analyzer": "standard",
                            "boost": 3
                        }
                    }
                },
                {
                    "term": {
                        "normalized2": {
                            "value": "idona",
                            "boost": 2
                        }
                    }
                },
                {
                    "match": {
                        "normalized": "idona"
                    }
                }
            ]
        }
    }
}

結果は、フィールドのステータスに従ってアルファベットの昇順でソートされます。ステータスには[active, canceled, old...]のようないくつかの値があり、クエリ内の可能性のあるすべての値に対してブーストのようなものが必要です。例えば、active boost 5, canceled boost 4, old boost 3 ...........................。このようなことは可能でしょうか?ありがとうございます。

どのように解決するのですか?

この場合 スクリプトによるカスタムソート を使用することで、あなたの望むものを実現することができます。

を利用したところです。 match_all クエリを作成した後、そこにクエリロジックを追加することもできますが、あなたが探しているソリューションは sort というセクションがあります。

必ず status キーワード タイプ

値によるカスタムソート

POST <your_index_name>/_search
{  
   "query":{  
      "match_all":{  

      }
   },
   "sort":[  
      { "_score": "desc" }, 
      {  
         "_script":{  
            "type":"number",
            "script":{  
               "lang":"painless",
               "inline":"if(params.scores.containsKey(doc['status'].value)) { return params.scores[doc['status'].value];} return 100000;",
               "params":{  
                  "scores":{  
                     "active":5,
                     "old":4,
                     "cancelled":3
                  }
               }
            },
            "order":"desc"
         }
      }
   ]
}

上記のクエリで、先に値を scores セクションを作成します。例えば、値が new という値にしたい場合 2 であれば、スコアは以下のようになります。

{  
   "scores":{  
      "active":5,
      "old":4,
      "cancelled":3,
      "new":6
   }
}

つまり、基本的にドキュメントは最初に _score そして、そのソートされたドキュメントに スクリプトソート が実行される。

なお、スクリプトソートは desc を表示させたいのだろうと理解しているので、本来は active の文書が一番上にあり、その後に他の値が続きます。自由に弄ってみてください。

お役に立てれば幸いです。