2017-08-29 61 views
0

查找類似主題(一式兩份提名)我們有一個網站,用戶可以發佈內容到網站後適度檢查內容,他們發佈的,標題說明是最重要的領域的內容,我們要防止用戶發佈類似的帖子所以我們尋找實現方法來找到類似的帖子和提示適度這些內容是非常相似的一些舊帖子和版主仔細檢查他們的重複,我的意思是警告他們作爲可疑重複,我們索引所有內容在彈性搜索和我的問題,我們必須寫最佳查詢。 這是代碼的一部分,我們試過,但在Elasticsearch

$nameDesc = $title->Title. ' ' . $item->Description; 

    $query = [ 
     '_source' => ['name', 'description', 'price'], 
     'query' => [ 
      'filtered' => [ 
       'query' => [ 
        'multi_match' => [ 
         'fields' => ['title', 'description'], 
         'type' => 'cross_fields', 
         'query' => $nameDesc 
        ] 
       ], 
       'filter' => [ 
        'not' => [ 
         'ids' => ['values' => [$item->ID]] 
        ] 
       ], 
      ], 
     ] 
    ]; 
    $dupeCandidates = $this->indexService->buildSearch('articles', $query)->setLimit(4)->get(); 

我想這是最好的,而不是CONCAT 標題說明做cross_fields多的比賽,嘗試兩個獨立的匹配查詢,或更好的解決方案。

簡明扼要我們在Elasticsearch的標題和描述中尋找最佳查詢檢測高相似內容。

更新

根據答案的一個

已建議我嘗試下面的代碼片段,但沒有結果(我想一個標題,在索引究竟存在)

GET /_search 
{ 
    "query":{ 
     "bool":{ 
     "must":{ 
      "more_like_this":{ 
       "fields":[ "title", "description" ], 
       "like": "EXAMPLE EXIST TILE", 
       "min_term_freq":1, 
       "max_query_terms":100, 
       "min_doc_freq":0 
      } 
     } 
     } 
    } 
} 

回答

1

根據文獻@ CS25提到一個很好的解決方案是使用more_like_this

{ 
      "min_score": 5, 
      "query": 
       {"filtered": { 
        "query": { 
         "bool": { 
          "must": { 
           "more_like_this": { 
            "fields": ["title","desc"], 
            "like": { 
             "doc": { 
              "title": item["title"], 
              "desc": item["desc"], 
             }, 
            }, 
            "min_term_freq": 1, 
            "max_query_terms": 100, 
            "min_doc_freq": 0 
           } 
          } 
         } 
        }, 
        "filter": { 
         "not": { 
          "term": { 
           "id": item["id"] 
          } 
         } 
        } 
       } 

       } 
     } 

編號:https://www.elastic.co/guide/en/elasticsearch/reference/5.5/query-dsl-mlt-query.html

1

matchmatch_phrase語句可以通過組合多次與這取決於你試圖完成什麼不同的分析儀索引你的領域中使用對方。一種方法是將字段(標題,說明)索引爲analyzednot_analyzed

Elasticsearch 2.x的

在Elasticsearch < 5.x中,如果索引字段作爲字符串,它們default to being analyzed。當定義multi-field(這可以是任何內容,下面的示例指定raw作爲用於not_analyzed字段的多字段)時,您只需要指定索引爲not_analyzed

PUT my_index 
{ 
    "mappings": { 
    "my_type": { 
     "properties": { 
     "title": { 
      "type": "string", 
      "fields": { 
      "raw": { 
       "type": "string", 
       "index": "not_analyzed" 
      } 
      } 
     }, 
     "description": { 
      "type": "string", 
      "fields": { 
      "raw": { 
       "type": "string", 
       "index": "not_analyzed" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

Elasticsearch 5.x的

在Elasticsearch的較新版本,限定field datatype將確定一個字段或多字段是否應進行分析,例如text (analyzed)keyword (not_analyzed)

PUT my_index 
{ 
    "mappings": { 
    "my_type": { 
     "properties": { 
     "description": { 
      "type": "text", 
      "fields": { 
      "raw": { 
       "type": "keyword" 
      } 
      } 
     }, 
     "title": { 
      "type": "text", 
      "fields": { 
      "raw": { 
       "type": "keyword" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

定義映射後,繼續和索引一些文件,如果你還沒有

POST _bulk 
{ "index" : { "_index" : "my_index", "_type" : "my_type", "_id" : "1" } } 
{ "title" : "Test Title 1", "description": "Test Description 1" } 
{ "index" : { "_index" : "my_index", "_type" : "my_type", "_id" : "2" } } 
{ "title" : "Test Title 2", "description": "Test Description 2" } 
{ "index" : { "_index" : "my_index", "_type" : "my_type", "_id" : "3" } } 
{ "title" : "Test Title 3", "description": "Test Description 3" } 

如果您的應用程序需要搜索的內容是相同OR相似的用戶輸入,你已經索引您的字段正確,您可以通過使用bool查詢來構建搜索文檔,該查詢使用matchmatch_phrase語句爲應用程序需要搜索以確定文檔是否存在的每個字段指定多個SHOULD子句。

GET my_index/my_type/_search 
{ 
    "query": { 
    "bool": { 
     "should": [ 
     { 
      "match_phrase": { 
      "title": "Test Title" 
      } 
     }, 
     { 
      "match_phrase": { 
      "description": "Test Title" 
      } 
     }, 
     { 
      "match": { 
      "title.raw": "Test Title" 
      } 
     }, 
     { 
      "match": { 
      "description.raw": "Test Title" 
      } 
     } 
     ] 
    } 
    } 
} 

在上面的例子中,使用TestTitleDescription值分別應與從索引爲text (analyzed),並Test Title 1Test Description 1值的字段的結果響應應該從索引爲keyword (not_analyzed)字段結果作出響應。這在Elasticsearch 5.5上進行了測試。

+0

tnx您的注意和花費時間,我們有索引數據彈性,什麼你的想法是在must部分放置標題匹配,並在should部分放置描述匹配? – zhilevan

+0

我厭倦了這一點,甚至沒有在確切的重複項目中產生結果。 – zhilevan

+0

您使用的是什麼版本的Elasticsearch?他們的搜索API從版本2.x開始已經改變。查看修改。 – dcd018