为了账号安全,请及时绑定邮箱和手机立即绑定

多线程中elasticsearch插入时如何保证唯一性?

多线程中elasticsearch插入时如何保证唯一性?

繁星淼淼 2023-12-13 16:27:04
我们有一些elasticsearch的文档。文档的唯一性是由一些字段共同决定的,java多线程判断是否存在和插入时如何保证唯一性。之前不知道有什么好的方法,所以就写了一个方法:我猜是否存在,如果不存在我就插入,这个方法是通过syncronized来修改的。但我发现这是一种非常低效的做法。/** * @param document */synchronized void selectAndInsert(Map<String, Object> document){    //Determine if it exists, insert it if it does not exist}我的映射如下: {"properties":{"pt_number":{ "type":"keyword" }, "pt_name":{"type":"keyword" },"pt_longitude":{ "type":"文本"},"pt_latitude":{"type":"text" },"rd_code":{ "type":"text" }, "rd_name":{ "type":"keyword"}, "area_code": {“类型”:“关键字”} ...等等 }}唯一性由area_code、pt_longitude 和pt_latitude 确定。插入文档时我会根据area_code、pt-longitude、pt_latitude判断是否存在,不存在则插入。java多线程运行时如何保证文档的唯一性?这个问题困扰了我一段时间。谁能帮助我,我将非常感激。
查看完整描述

3 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

仅通过索引中的属性无法以任何方式保证不存在此类文档。即使您检查它是否存在于索引中但没有看到它,从发出该操作的响应到 ES 接受您的索引请求之间也存在一段时间。

所以基本上你只有两种方法:

  • 保证索引操作的单次执行(漫长且不那么简单的方法,因为我们没有一次性系统)

  • 将文档唯一属性转换为文档 ID,因此即使索引操作重叠,它们也只会将相同的值写入同一文档(或者第二个及后续操作将失败,具体取决于请求选项)。

后一个非常简单,您有一些开箱即用的选项:

  • 按确定的顺序获取所有唯一属性并连接它们的字符串表示形式(丑陋)

  • 按确定的顺序获取所有唯一属性,连接它们的字节值并使用 Base64 进行编码(不太难看)

  • 按确定的顺序获取所有唯一属性,将它们传递给散列函数(md5、sha-X 系列,无论您喜欢什么)并使用结果的字符串表示形式。


查看完整回答
反对 回复 2023-12-13
?
九州编程

TA贡献1785条经验 获得超4个赞

常见的情况可能是您以某种方式发送了文档(例如 kafka)并希望确保没有重复项。据我所知,ElasticSearch 中没有这样的方法,尽管你可以在这里尝试一个技巧:

  • ElasticSearch 允许指定自定义文档 ID

  • 文档ID的长度被限制为512字节,不能用于正常的“处理”

您可能希望根据您的字段(如数据库中的主键)创建一个 ID。如果使用 _create ,那么仅当您的文档尚不存在时才会创建它。

但还有一些问题需要解决:如何生成ID?简单的串联可以工作,但前提是您确定总长度不会超过 512B。否则可以使用校验和 - 但冲突的可能性很小。如果收到几乎相同的文档该怎么办(您的密钥相同,但存在其他一些差异)。Elastic 只允许“替换”或“不替换”。您需要处理其他场景。


查看完整回答
反对 回复 2023-12-13
?
繁花不似锦

TA贡献1851条经验 获得超4个赞

如果您检测到插入,为什么不在插入完成后(和索引刷新...)检查是否没有重复项。第二种解决方案是使用批量插入更新数据包写入每个 X(= 将新文档存储在共享区域的列表中,因此您可以检查您的文档是否尚未存在,并每 10 秒写入此列表例子)。



查看完整回答
反对 回复 2023-12-13
  • 3 回答
  • 0 关注
  • 87 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信