在實際搜索中,若是商家信用良好,那有可能搜索的結果前幾條都是該商家的,這樣會引發其餘商家的不滿,所以須要干預一下排序,使每頁一個商家最多顯示兩條商品。俗稱N抽二,這在淘寶,天貓也是有此規則的。html
在elasticseasrch中,對外暴露的接口很少,想了幾天,最終採用elasticsearch 自帶的聚合功能來實現,具體參見elasticsearch
具體:ui
InitScriptFactory 初始化一個隊列htm
MapScriptFactory 將商品ID, 商家ID, 分數放入隊列排序
CombineFactory 對每一個商家取top100,合併全部商家,再排序,並返回top1000接口
ReduceScriptFactory 對全部分片的數據進行排序,而後N抽二,默認20個桶,將全部數據往這個20個桶裏放,若是發現這個桶已經滿了,找下一個桶,不然,若是發現該桶內已有該商家的兩個商品,也找下一個桶,不然能夠放到這個桶內。對於那些沒有放到任何桶內的商品,放到一個備用桶內,爲後續的補位預留(有可能到最後有的桶沒有滿)。隊列
這樣就實現了N抽二的簡單邏輯。固然這可能不是最優的方案,可是勉強能實現功能。ip