Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB:比较两个大集合的最快方法_Mongodb_Bloom Filter_Large Data - Fatal编程技术网

MongoDB:比较两个大集合的最快方法

MongoDB:比较两个大集合的最快方法,mongodb,bloom-filter,large-data,Mongodb,Bloom Filter,Large Data,我有一个MongoDB收藏,有超过2000万个文档(而且增长很快)。某些文档具有“用户id”(其他文档则没有) 我需要定期检查集合中是否存在某些用户id。但是有很多“一些”。10公里到10万公里 你会怎么做 第一个想法是提出一个大问题: $or : [ { 'user_id' : ... } , { ... } , ... ] 用我所有的10K到100K ID。。。但是它很慢,我不认为这是更好的方法。有人告诉我Redis的bloom过滤器,但Mongo似乎没有这样做 你认为有更好的方法吗?与b

我有一个MongoDB收藏,有超过2000万个文档(而且增长很快)。某些文档具有“用户id”(其他文档则没有)

我需要定期检查集合中是否存在某些用户id。但是有很多“一些”。10公里到10万公里

你会怎么做

第一个想法是提出一个大问题:

$or : [ { 'user_id' : ... } , { ... } , ... ]
用我所有的10K到100K ID。。。但是它很慢,我不认为这是更好的方法。有人告诉我Redis的bloom过滤器,但Mongo似乎没有这样做


你认为有更好的方法吗?与bloom过滤器一样,在我的情况下,<100%的精度是可以接受的。

您可以尝试使用
$in
进行设置比较:

db.users.find({ _id : { $in : [ 1, 2, 3, 4 ] } })
如果在要搜索的字段上有索引,则操作应该很快。如果您没有索引,并且您预计需要经常重复该查询,那么您肯定应该构建一个索引。如评论中所述,如果user_id字段仅出现在某些文档中,则稀疏索引将适合您的集合

我在IPython中做了一个基准测试,收集了大约2亿份文档,在一台规格相对较高的笔记本电脑上的测试数据库中:

import random
from pymongo import MongoClient

client = MongoClient()
db = client["anonymised"]

# generate 100K random ids for testing purposes
ids = [ random.randint(0, int(1e6)) for i in range 100000 ]

%time db.users.count({ "_id" : { "$in" : ids } })
CPU times: user 182 ms, sys: 75.5 ms, total: 257 ms
Wall time: 16.1 s
# returns 32631
如果您想在这方面有所改进,就必须考虑对数据库进行分片,以便在活动内存中保留更重要的部分。在内存中有整个工作集的生产环境中,此操作可能要快得多

相比之下,您最初采用的“$or”方法:

query = [ { "_id" : v } for v in ids ]

%time db.users.count({ "$or" : query })
CPU times: user 1.4 s, sys: 682 ms, total: 2.08 s
Wall time: 35min 30s

如果使用聚合框架,MongoDB支持使用$match进行过滤。你可能想使用索引。如果我理解得很好,问题是“如何编写一个查询来查找大量值集和集合中的值集之间的交集”。关键是如何传递“庞大的”值集进行比较。某种程度上是相关的:查询大小显然有16MB的限制——您可以随时部署自己的bloom筛选器。只要你不删除文件。(该死的5分钟限制)但请记住,这不是一个银弹。您将筛选出不在数据库中的用户,但仍必须查询通过筛选的用户。