在Elasticsearch
查找类似主题(一式两份提名)我们有一个网站,用户可以发布内容到网站后适度检查内容,他们发布的,标题和说明是最重要的领域的内容,我们要防止用户发布类似的帖子所以我们寻找实现方法来找到类似的帖子和提示适度这些内容是非常相似的一些旧帖子和版主仔细检查他们的重复,我的意思是警告他们作为可疑重复,我们索引所有内容在弹性搜索和我的问题,我们必须写最佳查询。 这是代码的一部分,我们试过,但在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
}
}
}
}
}
根据文献@ 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
可以使用MLT(更像这个)查询Elasticsearch。它可以很好地提供类似的结果。 看看这个链接实现:
https://www.elastic.co/guide/en/elasticsearch/reference/5.5/query-dsl-mlt-query.html
match
和match_phrase
语句可以通过组合多次与这取决于你试图完成什么不同的分析仪索引你的领域中使用对方。一种方法是将字段(标题,说明)索引为analyzed
和not_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
查询来构建搜索文档,该查询使用match
和match_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"
}
}
]
}
}
}
在上面的例子中,使用Test
,Title
和Description
值分别应与从索引为text (analyzed)
,并Test Title 1
或Test Description 1
值的字段的结果响应应该从索引为keyword (not_analyzed)
字段结果作出响应。这在Elasticsearch 5.5上进行了测试。
可以提供它的查询? – zhilevan
我看到了这个链接,看起来很好,但我正在寻找一个解决方案做两个领域的相似性,标题与标题和说明描述, – zhilevan