0

这是我的问题。我想在 mongodb 中创建一个集合,其中我有一个单词和它出现的次数。我在 python 中做它,它非常慢。这很可能是因为对于我拥有的每个单词,我检查它是否已经在数据库中(使用 *find_one*),如果是,获取它的频率,增加它并将其存储回来(使用update)当然,当单词不存在,我将其附加到列表并定期进行批量插入。

有没有更好的方法来做到这一点?单词的数量很大(可能有不同的语言)。首先使用 mongoDB 是正确的吗?我选择了 mongoDB,因为它很容易安装,而且我在 10 分钟内就学会了教程……

编辑- 也添加了代码。当我说大时,我的意思是一个大约 4 GB 大的文件,其中包含单词......

insertlist = []

def copy_to_db(word):
    global insertlist

    wordCollection = db['words']
    occurrence = wordCollection.find_one({'word' : word})
    if occurrence:
            n = occurrence['number']
            n = n + 1
            wordCollection.update({'word' : word}, {'$set' : {'number' : n}})
    else:
            insertlist.append({'word' : word, 'number' : 1})
            #wordCollection.insert({'word' : word, 'number' : 1})

    if len(insertlist) >= 5000:
            print("insert triggered ... ")
            wordCollection.insert(insertlist)
            insertlist = []

我称之为函数。对于每一个字。

4

1 回答 1

0

听起来你可以使用upserts。如果您使用 upsert,则不需要执行该获取/保存周期。

我不确定这是如何在 python 驱动程序中完成的,但在 JavaScript 中它看起来像:

db.words.update({"_id": "the_word" }, {"$inc": {"frequency": 1}}, true)

MongoDB 自动为 _id 字段创建索引。如果您的单词没有使用 _id 字段,那么为您的键创建索引很可能会有很大帮助。


编辑:为您提供更多想法

由于有很多数据,您可以使用 _id 字段作为您的单词。这样您就不需要创建另一个索引,并且更新会稍微快一些,因为在插入新文档时只需要更新一个索引。这是在插入速度是瓶颈的情况下。

虽然在插入大量数据时利用批量插入通常是一个好主意,但我不确定它是否对这种情况有太大​​帮助。这取决于您的数据。如果唯一词的比例很高,那么批量插入可能会很方便。但是,如果一遍又一遍地使用相同的词(我猜大多数语言都是这种情况),那么批量插入可能不会有太大帮助。

此外,您的批量插入似乎有问题。想想你是否第一次遇到一个词。它被插入到您的插入列表中。现在,如果在未插入前一批的情况下再次遇到相同的单词,则该单词的数字属性将为 1,这是不正确的。

你确定数据库是瓶颈吗?您是否已经确定没有其他性能不佳的代码?但无论如何我想,无论如何插入 4GB 的数据都需要一段时间。

于 2012-11-23T06:32:29.190 回答