mongodb 给数组插入不重复的内容

2019-01-06 01:22:07 +08:00
 JCZ2MkKb5S8ZX9pq

需求

mongodb 里有一个字段,比如tags,有多个来源,来源都是数组,需要插入并去重。
直观的方法是查询后去重,然后更新回去。
网上看到还有 addToSet 这个命令。
用两种方法都做了测试。

先建一个临时表

s = [i for i in range(10000)]
for i in range(10000):
    db['test'].insert_one({'test_set': s})

方法 1

查询 /用旧列表和新列表合并 /更新

s = [i for i in range(0, 20000, 2)]
for i in db['test'].find():
    i['test_set'] = sorted(set(i['test_set']) | set(s))
    db['test'].update_one({'_id': i['_id']}, 
                          {'$set': {'test_set': i['test_set']}})

方法 2

网上看到的,用 addToSet。

s = [i for i in range(0, 20000, 2)]
for i in db['test'].find():
    i['test_set'] = sorted(set(i['test_set']) | set(s))
    db['test'].update_one({'_id': i['_id']},
                          {'$addToSet': {'test_set': {'$each': s}}})

结论

方法 2 超级超级慢,可能是 each 之后做了太多次查重导致的。
本来还以为都在数据库端处理可能会快点,失败。
跟大家分享下实验结果。

附:$addToSet — MongoDB Manual

如果有其它好的方法欢迎讨论。

5689 次点击
所在节点    MongoDB
3 条回复
swulling
2019-01-06 01:58:54 +08:00
方法一有并发冲突问题,谨慎使用。
myKing
2020-02-04 16:31:52 +08:00
还有其他方法?
sego
2020-04-07 11:05:11 +08:00
看了[官网的文档]( https://docs.mongodb.com/manual/reference/operator/update/addToSet/),想不重复地添加元素到数组里,好像只能 addToSet 。
要不看下 CPU 占用高不高,不高的话多线程试试?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/524286

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX