elasticsearch同義詞和搜索相關(guān)度優(yōu)化

雖然docker方便.但是由于163鏡像版本太低.所以在本地搭了一個es.版本6.3.0;

首先說下這次研究的方向: 搜索框搜西紅柿,那么番茄是出不來的. 搜索米的時候.蝦米條比大米的相關(guān)度還高
暫時考慮的方案如下:
1.加入同義詞
2.相關(guān)度優(yōu)化.將字段排優(yōu)先級,名字的相關(guān)度提升
3.未雨綢繆,增加類似某寶某東一樣的,銷量高的排名也提升一點,具體如下


同義詞插件

插件1 :同義詞文件配置方式
插件2 :數(shù)據(jù)庫配置方式
原本想使用插件2. 兩種方式都是可以動態(tài)加載同義詞詞庫.所以配置好之后不需要修改詞庫就重啟es,
但是插件2的大佬一直沒有更新,所以我在6.3.0中加入插件報錯我沒有處理好暫時先使用插件1

插件2
項目支持6.x版本.但是tag上沒有,因此clone到本地.修改版本.然后maven打包.得到插件放到es的plugins下重啟es
github上有使用的實例.我的測試用例,這個成功之后,暫時先放一邊.先搞下相關(guān)度優(yōu)化

DELETE prod
PUT /prod
{
    "index" : {
        "analysis" : {
            "analyzer" : {
                "synonym" : {
                    "tokenizer" : "ik_max_word",
                    "filter" : ["remote_synonym"]
               }
            },
            "filter" : {
                "remote_synonym" : {
                    "type" : "dynamic_synonym",
                    "synonyms_path" : "synonym.txt",    //文件沒有就創(chuàng)建一個
                    "interval": 30          //由于本地跑.所以30s重新查一次.線上肯定不可以30s
                },
                "local_synonym" : {
                    "type" : "dynamic_synonym",
                    "synonyms_path" : "synonym.txt"
                }
            }
        }
    }
}


將項目中需要優(yōu)化的幾個字段抽取出來自己定義了一個精簡版的demo

PUT /prod/demo/_mapping
{
 
      "properties":{
        "name":{
          "type":"text",
           "analyzer": "synonym"
        },
        "description":{
           "type":"text",
           "analyzer": "ik_max_word"
        },
        "brandName":{
           "type":"text",
           "analyzer": "ik_max_word"
        },
        "labelName": {
           "type": "text",
           "analyzer": "ik_max_word"
        },
         "menuCategoryNamePath": {
           "type": "text",
           "analyzer": "ik_max_word"
        },
        "num":{
          "type": "integer"
        }
  }
}

原先的查詢代碼:

QueryBuilders.multiMatchQuery(((SearchProductReq) req).getSearchContent(),
                    PRODUCT_NAME,
                    BRAND_NAME,
                    DESCRIPTION,
                    LABEL_NAME,
                    MENU_CATEGORY_NAME_PATH);

等同于:

GET prod/demo/_search
{
  "query":{
    "multi_match": {
      "query": "米",
      "fields": ["name","description","brandName","labelName","menuCategoryNamePath"]
    }
  }
}

修改后,排分還待修正.暫時按這樣的分?jǐn)?shù):

   QueryBuilder  queryBuilder = QueryBuilders.boolQuery()
                    .should(QueryBuilders.matchQuery("name", "米").boost(0.8f))
                    .should(QueryBuilders.matchQuery("brandName", "米").boost(0.6f))
                    .should(QueryBuilders.matchQuery("labelName", "米").boost(0.6f))
                    .should(QueryBuilders.matchQuery("menuCategoryNamePath", "米").boost(0.2f))
                    .should(QueryBuilders.matchQuery("description", "米").boost(0.4f));


        FieldValueFactorFunctionBuilder factorFunctionBuilder = new FieldValueFactorFunctionBuilder("num");
        factorFunctionBuilder.factor(0.1f);
        factorFunctionBuilder.modifier(FieldValueFactorFunction.Modifier.LOG1P);
        FunctionScoreQueryBuilder boostMode = QueryBuilders
                .functionScoreQuery(queryBuilder, factorFunctionBuilder)
                .boostMode(CombineFunction.SUM);
        SearchRequestBuilder requestBuilder = client.prepareSearch(ESConstant.PRODUCT_INDEX)
                .setTypes(ESConstant.PRODUCT_TYPE);
        requestBuilder.setQuery(boostMode);

等同于:

GET prod/demo/_search
{
  "query":{
    "function_score": {
      "query": {
          "bool": {
      "should": [
        {
          "match": {
            "name": {"query": "大米","boost":0.8}
          }
        },
        {
          "match": {
            "brandName": {"query": "大米","boost":0.6}
          }
        },
        {
          "match": {
            "labelName": {"query": "大米","boost":0.6}
          }
        },
        {
          "match": {
            "description": {"query": "大米","boost":0.5}
          },
        {
          "match": {
            "menuCategoryNamePath": {"query": "大米","boost":0.2}
          }
        }
      ]
    }
      },
      "field_value_factor": {
        "field": "num",
        "modifier": "log1p",
        "factor": 0.1
      },
      "boost_mode": "sum"
    }
  }
}

提升相關(guān)度使用function_score參考官方文檔


加入同義詞,這個需要修改mapping.

PUT /prod/demo/_mapping
{
 
      "properties":{
        "name":{
          "type":"text",
           "analyzer": "synonym"
        },
        "description":{
           "type":"text",
           "analyzer": "synonym"
        },
        "brandName":{
           "type":"text",
           "analyzer": "synonym"
        },
        "labelName": {
           "type": "text",
           "analyzer": "synonym"
        },
         "menuCategoryNamePath": {
           "type": "text",
           "analyzer": "synonym"
        },
        "num":{
          "type": "integer"
        }
  }
}

這時候在config的synonym.txt文件中增加同義詞.比如比如插入數(shù)據(jù):


POST /prod/demo/2
{
   "name":"大米",
    "description":"稻香大米",
    "brandName":"COCO",
    "labelName":"大米",
   "menuCategoryNamePath":"食品|飲料",
    "num":3
}
POST /prod/demo/3
{
  "name":"蝦米條",
   "description":"蝦米條",
    "brandName":"COCO",
    "labelName":"蝦米條",
    "menuCategoryNamePath":"食品|零食",
     "num":1
}
POST /prod/demo/4
{
   "name":"惠宜 珍珠米 10KG",
   "description":"惠宜 珍珠米 10KG",
    "brandName":"COCO",
    "labelName":"惠宜",
    "menuCategoryNamePath":"食品|飲料",
     "num":5
}
POST /prod/demo/5
{
   "name":"口口牌 泰國進口 泰國茉莉香米",
   "description":"口口牌 泰國進口 泰國茉莉香米",
    "brandName":"COCO",
    "labelName":"口口牌",
    "menuCategoryNamePath":"食品|飲料",
     "num":3
}

ik分詞器不會拆大米.所以大米和米是兩個條件. 如果把米/大米設(shè)置成近義詞.name這時候.搜米和大米都能收到上述商品.并且相關(guān)度也有有一定變化.

首先沒有淘寶京東那么智能,但是由于我剛接觸es.暫時先這樣優(yōu)化下,
測試數(shù)據(jù).很假,主要測試下效果.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疗锐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子席赂,更是在濱河造成了極大的恐慌蓄拣,老刑警劉巖擅腰,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叠蝇,死亡現(xiàn)場離奇詭異毕匀,居然都是意外死亡铸鹰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門皂岔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹋笼,“玉大人,你說我怎么就攤上這事躁垛∑侍海” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵教馆,是天一觀的道長逊谋。 經(jīng)常有香客問我,道長土铺,這世上最難降的妖魔是什么胶滋? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮悲敷,結(jié)果婚禮上究恤,老公的妹妹穿的比我還像新娘。我一直安慰自己后德,他們只是感情好部宿,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著探遵,像睡著了一般窟赏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上箱季,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音棍掐,去河邊找鬼藏雏。 笑死,一個胖子當(dāng)著我的面吹牛作煌,可吹牛的內(nèi)容都是我干的掘殴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼粟誓,長吁一口氣:“原來是場噩夢啊……” “哼奏寨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鹰服,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤病瞳,失蹤者是張志新(化名)和其女友劉穎揽咕,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體套菜,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡亲善,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了逗柴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛹头。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖戏溺,靈堂內(nèi)的尸體忽然破棺而出渣蜗,到底是詐尸還是另有隱情,我是刑警寧澤旷祸,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布耕拷,位于F島的核電站,受9級特大地震影響肋僧,放射性物質(zhì)發(fā)生泄漏斑胜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一嫌吠、第九天 我趴在偏房一處隱蔽的房頂上張望止潘。 院中可真熱鬧,春花似錦辫诅、人聲如沸凭戴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽么夫。三九已至,卻和暖如春肤视,著一層夾襖步出監(jiān)牢的瞬間档痪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工邢滑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留腐螟,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓困后,卻偏偏與公主長得像乐纸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子摇予,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355