使用Mongoimport
将CSV
文件导入我的数据库后,我想为每个文档添加一个新字段或元素。并且,此新字段的每个数据是索引号加上2.
Dim documents = DB.GetCollection(Of BsonDocument)(collectionName).Find(filterSelectedDocuments).ToListAsync.Result
For Each doc in documents
DB.GetCollection(Of BsonDocument)(collectionName).UpdateOneAsync(
Builders(Of BsonDocument).Filter.Eq(Of ObjectId)("_id", doc.GetValue("_id").AsObjectId),
Builders(Of BsonDocument).Update.Set(Of Integer)("increment.value", documents.IndexOf(doc) + 2).Wait()
Next
如果我要导入超过一百万的数据,是否有更好的方法来实现此目的,例如使用UpdateManyAsync
?
答案 0 :(得分:1)
正如旁注:由于您到处都有Wait()
和Result
,因此Async
方法似乎不会产生太大的影响。感。此外,由于任何地方都没有.Sort()
,因此您的逻辑显示有缺陷。因此,您无法保证退回文件的顺序。它是否被称为每个文档只是获得一种随机但唯一且不断增加的数字?
无论如何,为了加快速度,你真的想要修补你的CSV文件并编写增加的" increment.value"在导入之前直接进入它。这样,您就可以直接在MongoDB中获得价值,而无需再次查询和更新导入的数据。
如果这不是一个选项,您可以像这样优化您的代码:
_id
- 这就是您所需要的全部内容,因为需要从MongoDB传输/反序列化的数据少得多,这将对您的.find()
性能产生重大影响。< / LI>
Enumerable
,而不是使用完全填充的列表。yield
语义来实现更好的流式传输。但是,这有点复杂,甚至可能不需要。以下内容可以让您加快速度:
' just some cached values
Dim filterDefinitionBuilder = Builders(Of BsonDocument).Filter
Dim updateDefinitionBuilder = Builders(Of BsonDocument).Update
Dim collection = DB.GetCollection(Of BsonDocument)(collectionName)
' load only _id field
Dim documentIds = collection.Find(filterSelectedDocuments).Project(Function(doc) doc.GetValue("_id")).ToEnumerable()
' bulk write buffer (pre-initialized to size 1000 to avoid memory traffic upon array expansion)
Dim updateModelsBuffer = new List(Of UpdateOneModel(Of BsonDocument))(1000)
' starting value for our update counter
Dim i As Long = 2
For Each objectId In documentIds
' for every document we want one update command...
' ...that finds exactly one document identified by its _id field
Dim filterDefinition = filterDefinitionBuilder.Eq(Of ObjectId)("_id", objectId)
' ...and updates the "increment.value" with our running counter
Dim updateDefinition = updateDefinitionBuilder.Set(Of Integer)("increment.value", i)
updateModelsBuffer.Add(New UpdateOneModel(Of BsonDocument)(filterDefinition, updateDefinition))
' every e.g. 1000 documents
If updateModelsBuffer.Count = 1000
' we flush the contents to the database
collection.BulkWrite(updateModelsBuffer)
' and we empty our buffer list
updateModelsBuffer.Clear()
End If
i = i + 1
Next
' flush left over commands that have not been written yet in case we do not have a multiple of 1000 documents
collection.BulkWrite(updateModelsBuffer)