競合他社の価格監視サービスにElasticsearchを使用した製品マッチング

2017年に、競合他社の価格監視サービスを開発するというアイデアが生まれました。 他の同様のサービスからのその際立った特徴は、商品の毎日の自動マッチングの機能であることでした。 これを行う方法に関する情報がほぼ完全に不足しているため、価格監視サービスは、顧客自身またはサービスオペレーターが0.2〜1ルーブルの価格でマッチングの事実を手動で比較する可能性のみを提供しました。 たとえば、10のサイトとそれぞれに20,000の製品がある実際の状況では、手動の照合がすでに長すぎて高価であるため、プロセスの自動化が必要になります。



自動照合へのアプローチは、 Elaticsearchテクノロジーを使用した多数の競合薬局の例で以下に説明します。



環境の説明



  1. OS:Windows 10
  2. 根拠:Elaticsearch 6.2
  3. リクエストのクライアント:Postman 6.2


Elaticsearchのセットアップ



1回の要求での製品フィールドマッパーアナライザーの構成



PUT http://localhost:9200/app { "mappings": { "product": { "properties": { "name": { "type": "text", "analyzer": "name_analyzer" #        }, "manufacturer": { "type": "text" }, "city_id": { "type": "integer" }, "company_id": { "type": "integer" }, "category_id": { "type": "integer" }, } } }, "settings": { "index": { "analysis": { "analyzer": { "name_analyzer": { "type": "custom", "tokenizer": "standard", #        ,       "char_filter": [ "html_strip", #       html  "comma_to_dot_char_filter" #    ,     ], "filter": [ "word_delimeter_filter", #     "synonym_filter", #    "lowercase" #      ] } }, "filter": { "synonym_filter": { "type": "synonym_graph", "synonyms": [ ", ", ", ", ", ", ", , ", ", ", ", , , ", ", ", ", ", ", , ", ", , ", ", , , -, -", ", , ", ", , , ", ", ", ", ", ", , ", ", , ", ", ", ", ", ", ", ", ", ", , , ", ", ", ", g", "ml, " ] }, "word_delimeter_filter": { "type": "word_delimiter", "type_table": [ ". => DIGIT", #       "- => ALPHANUM", "; => SUBWORD_DELIM", "` => SUBWORD_DELIM" ] } }, "char_filter": { "comma_to_dot_char_filter": { "type": "mapping", "mappings": [ ", => ." ] } } } } } }
      
      





たとえば、アナライザー「name_analyzer」が薬の名前「Hyoxysone 10mg + 30mg / g 10 gのチューブを外用する軟膏」の内訳を調べることができます。 request _analyzeを使用します。



 POST http://localhost:9200/app/_analyze { "analyzer" : "name_analyzer", "text" : " 10+30/      10" }
      
      





結果

 { "tokens": [ { "token": "", "start_offset": 0, "end_offset": 9, "type": "<ALPHANUM>", "position": 0 }, { "token": "10", "start_offset": 10, "end_offset": 12, "type": "<ALPHANUM>", "position": 1 }, { "token": "", "start_offset": 12, "end_offset": 14, "type": "<ALPHANUM>", "position": 2 }, { "token": "30", "start_offset": 15, "end_offset": 17, "type": "<ALPHANUM>", "position": 3 }, { "token": "", "start_offset": 17, "end_offset": 19, "type": "<ALPHANUM>", "position": 4 }, { "token": "g", "start_offset": 20, "end_offset": 21, "type": "SYNONYM", #,   "g"   SYNONYM,  ,          ", g" "position": 5 }, { "token": "", "start_offset": 20, "end_offset": 21, "type": "<ALPHANUM>", "position": 5 }, { "token": "", "start_offset": 22, "end_offset": 26, "type": "<ALPHANUM>", "position": 6 }, { "token": "", "start_offset": 27, "end_offset": 30, "type": "<ALPHANUM>", "position": 7 }, { "token": "", "start_offset": 31, "end_offset": 40, "type": "<ALPHANUM>", "position": 8 }, { "token": "", "start_offset": 41, "end_offset": 51, "type": "<ALPHANUM>", "position": 9 }, { "token": "", "start_offset": 52, "end_offset": 56, "type": "<ALPHANUM>", "position": 10 }, { "token": "10", "start_offset": 57, "end_offset": 59, "type": "<ALPHANUM>", "position": 11 }, { "token": "g", "start_offset": 59, "end_offset": 60, "type": "SYNONYM", "position": 12 }, { "token": "", "start_offset": 59, "end_offset": 60, "type": "<ALPHANUM>", "position": 12 } ] }
      
      





テストデータの入力



リクエスト_bulk



 POST http://localhost:9200/_bulk { "index": { "_index": "app", "_type": "product", "_id": 195111 } } { "name": " 10+30/      10", "manufacturer": "   ", "city_id": 1, "company_id": 2, "category_id": 1 } { "index": { "_index": "app", "_type": "product", "_id": 195222 } } { "name": "     10 +30 /: 10 ", "manufacturer": "", "city_id": 1, "company_id": 3, "category_id": 1 }
      
      





マッピング検索



競合他社の類似製品をすべて検索したいクライアントの製品に特性を持たせる



 { "name": "     10 +30 /   10 ", "manufacturer": "   ", "city_id": 1, "company_id": 1, "category_id": 1 }
      
      





ディレクトリを使用して、製品の名前から薬の名前選択します。 この場合、単語「Hyoxysone」。 この言葉は必須の基準です。



また、名前からすべての数字を切り取ります-「10 30 10」。これも不可欠な基準です。 さらに、特定の数が2回含まれていた場合、見つかった商品に2回表示されるはずです。そうでない場合、間違った商品と一致する可能性が高くなります。



_検索リクエスト



 GET http://localhost:9200/app/product/_search { "query": { "bool": { "filter": [ { "terms": { "company_id": [ 2, 3, 4, 5, 6, 7, 8 ] } }, { "term": { "city_id": { "value": 1, "boost": 1 } } }, { "term": { "category_id": { "value": 1, "boost": 1 } } } ], "must": [ { "bool": { "should": [ { "match": { "name": { "query": "    + /   ", "boost": 1, "operator": "or", "minimum_should_match": 0, "fuzziness": "AUTO" } } } ], "must": [ { "match": { "name": { "query": "", "boost": 2, "operator": "or", "minimum_should_match": "70%", "fuzziness": "AUTO" } } }, { "match_phrase": { "name": { "query": "10 30 10", "boost": 2, "slop": 100 } } } ] } } ], "should": [ { "bool": { "should": [ { "match": { "manufacturer": { "query": "   ", "boost": 1, "operator": "or", "minimum_should_match": "70%", "fuzziness": "AUTO" } } }, { "match": { "manufacturer": { "query": "alenta armacevtika ", "boost": 1, "operator": "or", "minimum_should_match": "70%", "fuzziness": "AUTO" } } } ] } } ] } }, "highlight": { "fields": { "name": {} } }, "size": 50 }
      
      





出力では、一致するフラグメントを含む商品のIDと、名前と分析のスコアを取得します。





おわりに



説明されている方法では、100%の照合精度は得られませんが、商品の手動照合のプロセスは非常に容易になります。 絶対的な精度を必要としないタスクにも適しています。

一般に、追加のヒューリスティックを使用して検索クエリを改善し、同義語の数を増やすと、ほぼ満足のいく結果を得ることができます。

さらに、古いi7で実行されたパフォーマンステストは良い結果を示しました。 200,000個の製品の配列で10回の検索クエリが数秒以内に実行されます。 ここで医学のこの実例を見ることができます



コメント内の方法に一致するオプションを提案します。



ご清聴ありがとうございました!



All Articles