Php 在Elasticsearch中查找类似主题(重复命名)
我们有一个网站,用户可以在网站上发布内容,经过审核后检查他们发布的内容,标题和描述是内容最重要的领域,我们希望防止用户发布类似的帖子,因此我们希望实现一种方法来查找类似的帖子,并提示这些内容与一些旧帖子非常相似,版主会仔细检查这些内容是否重复,我的意思是警告版主将其视为可疑的重复内容,我们在弹性搜索中索引所有内容,我的问题是我们必须编写的最佳查询。 这是我们尝试过的代码的一部分,但是Php 在Elasticsearch中查找类似主题(重复命名),php,elasticsearch,lucene,Php,elasticsearch,Lucene,我们有一个网站,用户可以在网站上发布内容,经过审核后检查他们发布的内容,标题和描述是内容最重要的领域,我们希望防止用户发布类似的帖子,因此我们希望实现一种方法来查找类似的帖子,并提示这些内容与一些旧帖子非常相似,版主会仔细检查这些内容是否重复,我的意思是警告版主将其视为可疑的重复内容,我们在弹性搜索中索引所有内容,我的问题是我们必须编写的最佳查询。 这是我们尝试过的代码的一部分,但是 $nameDesc = $title->Title. ' ' . $item->Descri
$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 Title和Description更好,可以进行跨字段多匹配,也可以尝试两个单独的匹配查询,或者更好的解决方案
简而言之,我们正在寻找最佳查询,通过Elasticsearch中的标题和描述检测高度相似的内容
更新
根据提出的答案之一,我尝试了以下代码片段,但没有结果(我尝试了一个完全存在于索引中的标题)
您可以使用Elasticsearch的MLT(更像这样)查询。它可以很好地给出类似的结果。
查看此链接以了解实施:
您可以使用Elasticsearch的MLT(更像这样)查询。它可以很好地给出类似的结果。
查看此链接以了解实施:
match
和match\u phrase
语句可以通过使用不同的分析器多次索引字段来相互组合使用,具体取决于您要完成的任务。一种方法是将字段(标题、描述)索引为已分析的
和未分析的
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"description": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
},
"title": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
}
Elasticsearch 2.x
在Elasticsearch<5.x中,如果将字段索引为字符串,则它们将被删除。在定义时,您只需将索引指定为“未分析”(这可以是任何内容,下面的示例将“未分析的”字段指定为“未分析的”字段的多字段)
Elasticsearch 5.x
在Elasticsearch的较新版本中,定义a将决定是否应分析一个字段或多个字段,例如文本(已分析)
和关键字(未分析)
定义映射之后,如果您还没有为一些文档编制索引,请继续操作
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" }
如果您的应用程序需要搜索与用户输入相同或类似的内容,并且您已经正确地为字段编制了索引,您可以使用bool
查询来构建搜索文档,该查询使用match
和match\u 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"
}
}
]
}
}
}
在上面的示例中,使用
测试
,标题
和说明
值应分别使用索引为文本(分析)
的字段的结果进行响应,测试标题1
或测试说明1
值应使用索引为关键字(未分析)的字段的结果进行响应
。这在Elasticsearch 5.5上进行了测试 match
和match\u phrase
语句可以通过使用不同的分析器多次索引字段来相互组合使用,具体取决于您要完成的任务。一种方法是将字段(标题、描述)索引为已分析的
和未分析的
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"description": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
},
"title": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
}
Elasticsearch 2.x
在Elasticsearch<5.x中,如果将字段索引为字符串,则它们将被删除。在定义时,您只需将索引指定为“未分析”(这可以是任何内容,下面的示例将“未分析的”字段指定为“未分析的”字段的多字段)
Elasticsearch 5.x
在Elasticsearch的较新版本中,定义a将决定是否应分析一个字段或多个字段,例如文本(已分析)
和关键字(未分析)
定义映射之后,如果您还没有为一些文档编制索引,请继续操作
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" }
如果您的应用程序需要搜索与用户输入相同或类似的内容,并且您已经正确地为字段编制了索引,您可以使用bool
查询来构建搜索文档,该查询使用match
和match\u 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"
}
}
]
}
}
}
在上面的示例中,使用
测试
,标题
和说明
值应分别使用索引为文本(分析)
的字段的结果进行响应,测试标题1
或测试说明1
值应使用索引为关键字(未分析)的字段的结果进行响应
。这在Elasticsearch 5.5上进行了测试 根据Ref@cs25所述,一个很好的解决方案是使用更多类似的
{
"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"]
}
}
}
}
}
}
Ref:根据Ref@cs25所述,一个好的解决方案是使用更像这个
{
"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"]
}
}
}
}
}
}
Ref:你能提供它的查询吗?我看到了那个链接,看起来不错,但我正在寻找一个解决方案,在两个字段中做相似性,标题与标题,描述与描述,你能提供它的查询吗?我看到了那个链接,看起来不错,但我正在寻找一个解决方案,在两个字段中做相似性,标题与标题和描述与描述,tnx为您尝试和花费时间,我们有弹性的索引数据,您对将标题匹配放在“必须”部分和将描述匹配放在“应该”部分有什么想法?我厌倦了这一点,甚至不会产生精确的重复项。弹性的版本是什么