MongoDB更新/ Upsert问题 - 与架构相关

时间:2011-08-05 10:24:23

标签: schema mongodb pymongo document-oriented-db

我在MongoDB中表示数据时遇到问题。我正在使用这种模式设计,其中日期和单词的组合是唯一的。

{'date':2-1-2011,
'word':word1'
users = [user1, user2, user3, user4]}

{'date':1-1-2011,
'word':word2'
users = [user1, user2]}

有固定数量的日期,大约200;每个日期可能有100k +单词;和100k +用户。

我用如下算法插入记录:

while records exist:
    message, user, date = pop a record off a list
    words = set(tokenise(message))

    for word in words:
        collection1.insert({'date':date, 'word':word}, {'user':user})
        collection2.insert('something similar')
        collection3.insert('something similar again')
        collection4.insert('something similar again')

但是,这种模式导致了极大的收藏,而且糟糕的表现非常可怕。我在四个集合中的每一个中插入不同的信息,因此对数据库进行了大量的操作。

我正在考虑以这样的格式表示数据,其中单词和用户数组是集合。

{'date':'26-6-2011',
 'words': [
'word1': ['user1', 'user2'],
'word2': ['user1']
'word1': ['user1', 'user2', 'user3']]}

这背后的想法是减少数据库操作的数量。因此,对于算法的每个循环,我只对每个集合执行一次更新。但是,我不确定如何对此执行更新/ upsert,因为对于算法的每个循环,我可能需要插入一个新单词,用户或两者。

有人可以推荐更新此文档的方法,还是有人可以建议替代架构?

由于

2 个答案:

答案 0 :(得分:0)

Upsert非常适合动态扩展文档。不幸的是,如果你在更新对象中有一个原子修饰符操作,我只发现它正常工作。像这里的$ addToSet(mongo shell代码):

db.words为空。使用upsert为给定日期添加第一个文档。

var query = { 'date' : 'date1' }                        
var update = { $addToSet: { 'words.word1' :  'user1' } }
db.words.update(query,update,true,false)                

检查对象。

db.words.find();                                        
{ "_id" : ObjectId("4e3bd4eccf7604a2180c4905"), "date" : "date1", "words" : { "word1" : [ "user1" ] } }

现在在一次更新中为第一个单词和另一个单词添加更多用户。

var update = { $addToSet: { 'words.word1' : { $each : ['user2', 'user4', 'user5'] }, 'words.word2': 'user3' } }
db.words.update(query,update,true,false) 

再次检查对象。

db.words.find()                                                                                                
{ "_id" : ObjectId("4e3bd7e9cf7604a2180c4907"), "date" : "date1", "words" : { "word1" : [ "user1", "user2", "user4", "user5" ], "word2" : [ "user3" ] } }

答案 1 :(得分:0)

我正在使用MongoDB插入105mil记录,每个记录包含~10个属性。我只是删除并重新插入所有内容,而不是使用更改来更新此数据集。我发现这种方法比单独触摸每一行更快,看看它是否是我需要更新的一行。如果您创建JSON格式的文本文件并使用MongoDB的mongoimport工具,您将获得更好的插入速度。

  1. 将您的数据格式化为JSON txt文件(每个集合一个文件)
  2. mongoimport每个文件并指定要插入的集合