2017-08-29 70 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