我试图使用它的MinHash实现查询接近重复的Elasticsearch索引。我使用在容器中运行的Python客户机来索引和执行搜索。
我的语料库是一个JSONL文件,有点像这样:
{"id":1, "text":"I'd just like to interject for a moment"}
{"id":2, "text":"I come up here for perception and clarity"}
...我成功地创建了一个Elasticsearch索引,尝试使用自定义设置和分析器,并从官方例子和MinHash文档获得灵感。
def create_index(client):
client.indices.create(
index="documents",
body={
"settings": {
"analysis": {
"filter": {
"my_shingle_filter": {
"type": "shingle",
"min_shingle_size": 5,
"max_shingle_size": 5,
"output_unigrams": False
},
"my_minhash_filter": {
"type": "min_hash",
"hash_count": 10,
"bucket_count": 512,
"hash_set_size": 1,
"with_rotation": True
}
},
"analyzer": {
"my_analyzer": {
"tokenizer": "standard",
"filter": [
"my_shingle_filter",
"my_minhash_filter"
]
}
}
}
},
"mappings": {
"properties": {
"name": {"type": "text", "analyzer": "my_analyzer"}
}
},
},
ignore=400,
)我验证了通过Kibana创建索引并没有什么大问题,而且通过访问设置,我得到了一些看起来很有条理的东西:

但是,使用以下方法查询索引:
def get_duplicate_documents(body, K, es):
doc = {
'_source': ['_id', 'body'],
'size': K,
'query': {
"match": {
"body": {
"query": body,
"analyzer" : "my_analyzer"
}
}
}
}
res = es.search(index='documents', body=doc)
top_matches = [hit['_source']['_id'] for hit in res['hits']['hits']]即使我将我的res['hits']设置为与我的语料库中一个条目的文本完全匹配,我的body也始终是空的。换句话说,如果我尝试作为body的值,就不会得到任何结果。
"I come up here for perception and clarity"或者是像
"I come up here for perception"虽然理想情况下,我希望这个过程返回接近重复的,分数是查询的Jaccard相似性和通过MinHash获得的接近重复的近似。
我的查询和/或索引Elasticsearch的方式有什么问题吗?我是不是完全错过了别的什么?
P.S.:您可以查看https://github.com/davidefiocco/dockerized-elasticsearch-duplicate-finder/tree/ea0974363b945bf5f85d52a781463fba76f4f987的一个非功能的,但希望可以重复的例子(我也将更新回购,因为我找到了一个解决方案!)
发布于 2020-08-03 14:21:44
以下是一些你应该反复检查的事情,因为它们可能是罪魁祸首:
client.indices.create方法中的body param中的“名称”更改为"text“,因为json文档中有一个名为text的字段:
“映射”:{“属性”:{“文本”:{“类型”:“文本”,“分析器”:"my_analyzer"}generate_actions()方法(跟随文献资料 ):
对于语料库中的elem :产生{ "_op_type":“索引”"_index":“文档”,"_id":elem"id","_source":elem"text“}
顺便说一句,如果您正在为pandas数据文件建立索引,您可能需要检查实验性的官方库伊兰。minhash令牌过滤器,因此Lucene将在哈希中转换text字段中的文本。因此,您可以使用散列来查询此字段,而不是像在示例"I come up here for perception and clarity"中那样使用字符串。因此,使用它的最佳方法是检索字段text的内容,然后在Elasticsearch中查询检索到的相同值。然后,_id元字段不在_source元字段中,因此您应该将get_duplicate_documents()方法更改为:
def get_duplicate_documents(body,K,es):doc ={ '_source':'text','size':K,'query':{ "match":{ "text":{#i更改了这一行!“查询”:body } res = es.search(index='documents',body=doc) #也更改了列表理解!top_matches =[(点击‘_id’,点击‘_source’)表示hit in res‘’hits‘]https://stackoverflow.com/questions/63221732
复制相似问题