以前↓の記事でやったようにFunctions Scoreで複数条件を組みあわせてscoreを作りソートをしていたが、 複雑になってきて限界がきた。
ElasticsearchのFunction score queryでBoolean値や日付をソートに使う - GAミント至上主義
scoreの限界
scoreは最終的に32bitのintの正の値する必要があること。
2つ3つぐらいなら、100とか1000とか位を分けてなんとかできたけど、例えば求人サイトの給料順にしようとすると日給の場合、万単位なので、それだけで5桁は必要になり、他との組み合わせはかなり難しい。
負の値は使えないのも不便。
さらに募集集中、停止中、などなど他の条件が増えてくると厳しい。
複数sort
最初からそうすればよかったのだけど、リスエスト時のsortにscriptを使えた。
scriptの中はfunction scoreと同様に書ける。
さらにsortは配列にできるので↓のような感じにする。 フラグ系も0、1にしてtypeはnumberにそろえている。 求人サイトでは更新日からの日数、給料などでやっている。
[
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "# 数字返すスクリプト"
},
"order": "asc"
}
},
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "# 数字返すスクリプト"
},
"order": "asc"
}
},
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "# 数字返すスクリプト"
},
"order": "asc"
}
},
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "# 数字返すスクリプト"
},
"order": "asc"
}
}
]
レスポンスのhitsをconsole.log(body.hits.hits.map((hit) => hit.sort))出すとこんな感じ。
[ [ 1, 0, 1, 132 ], [ 1, 0, 1, 132 ], [ 1, 0, 1, 133 ], [ 1, 0, 1, 133 ], [ 1, 0, 1, 136 ], [ 1, 0, 1, 136 ], [ 1, 0, 1, 136 ], [ 1, 0, 1, 136 ], [ 1, 0, 1, 139 ], [ 1, 0, 1, 199 ], [ 1, 1, 0, 297 ], [ 1, 1, 0, 483 ], [ 1, 1, 0, 786 ], [ 1, 1, 0, 832 ], [ 0, 0, 0, 460 ], [ 0, 0, 0, 460 ], [ 0, 1, 0, 460 ], [ 0, 1, 0, 460 ] ]
あんまり複雑だったり、多かったりするとCPUを喰いそうだけど、今のところ大きな差はないので大丈夫そう