elasticsearch,lucene,Php,elasticsearch,Lucene" /> elasticsearch,lucene,Php,elasticsearch,Lucene" />

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为您尝试和花费时间,我们有弹性的索引数据,您对将标题匹配放在“必须”部分和将描述匹配放在“应该”部分有什么想法?我厌倦了这一点,甚至不会产生精确的重复项。弹性的版本是什么