我想只在以前的记录中插入记录,例如我有一个表用户,我想只添加带有电话号码的唯一用户
{"name":"john smith", "Age":30 , "phone_number": "556"}
如果要添加具有相同电话号码的其他用户,我将无法添加它们。目前我正在尝试使用过滤器来确定我是否有该电话号码的现有记录
r.db(DB).table('users').filter(
{'phone_number': new_practice['phone_number']},
default=r.error()).run(conn)
这就是我尝试使用该方法来查找用户是否存在但是似乎没有给我我想要的内容
答案 0 :(得分:4)
使用RethinkDB没有好办法安全地。这在issue on github中已经讨论过,并且与独特的二级索引有关并且保证了自动性。实质上,你必须做两个操作。首先搜索电话号码是否已经存在,然后添加记录,如果它不是。
RethinkDB甚至不支持唯一的二级索引 非分片表。 (来源:Using secondary indexes in RethinkDB)
所以我们有一个竞争条件。两个请求可以同时运行,同时返回电话号码不存在,然后最终都插入新记录。以下不安全代码将执行此操作:
new_record = {"name": "john smith", "Age": 30, "phone_number": "556"}
filter_predicate = {"phone_number": new_record["phone_number"]}
test = r.table('users').filter(filter_predicate).count().eq(0)
r.branch(test, r.table('users').insert(new_record), None).run()
以下是运行它的输出:
In [92]: for document in r.table('users').run(): print(document)
In [93]: new_record = {"name": "john smith", "Age": 30, "phone_number": "556"}
In [94]: filter_predicate = {"phone_number": new_record["phone_number"]}
In [95]: test = r.table('users').filter(filter_predicate).count().eq(0)
In [96]: r.branch(test, r.table('users').insert(new_record), None).run()
Out[96]:
{u'deleted': 0,
u'errors': 0,
u'generated_keys': [u'2c0ffb27-cfdb-44e7-a416-4f7be5d97ea9'],
u'inserted': 1,
u'replaced': 0,
u'skipped': 0,
u'unchanged': 0}
In [97]: for document in r.table('users').run(): print document
{u'phone_number': u'556', u'Age': 30, u'id': u'2c0ffb27-cfdb-44e7-a416-4f7be5d97ea9', u'name': u'john smith'}
In [98]: r.branch(test, r.table('users').insert(new_record), None).run()
In [99]: for document in r.table('users').run(): print document
{u'phone_number': u'556', u'Age': 30, u'id': u'2c0ffb27-cfdb-44e7-a416-4f7be5d97ea9', u'name': u'john smith'}
想到的一种解决方法是优雅地尝试失败。也就是说,我们会进行初步检查以查看文档是否存在,如果不是我们添加它。然后我们必须检查重复项。如果发现重复,请清理。我们需要某种打破平局,例如在插入文件时(最早是获胜者)。任何期望我们的文档具有唯一电话号码的查询也需要考虑到这一点。如果两个文件具有相同的电话号码按时间顺序升序并选择第一个。