使用 C# Driver 2.1.1 存储在 MongoDb 集合中的对象的最大大小是多少?

Posted

技术标签:

【中文标题】使用 C# Driver 2.1.1 存储在 MongoDb 集合中的对象的最大大小是多少?【英文标题】:What is the maximum size of an object to store in a MongoDb collection using the C# Driver 2.1.1? 【发布时间】:2016-07-05 10:11:27 【问题描述】:

我使用 mongoDB C# 驱动程序 2.1.1 在 mongoDb 集合中存储和检索文档。到目前为止,这一直运行良好,直到一个文档正确被存储但驱动程序无法读回。

我使用 robomongo(一个用于监控我的集合中内容的用户界面)并操作存储的对象得出了这个结论。 它包含一组元素(大约 4000 个子元素),如果我删除了足够多的元素,文档最终可以再次检索。

使用的代码行是:

    public Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken))
    
        return MongoQueryable.FirstOrDefaultAsync(_collection, predicate, cancellationToken);
    

在你问之前,我首先想到的是我的子元素集中的一个特定元素在被序列化/反序列化时遇到了一些问题,并且正在创建问题。我通过随机删除集合的元素进行了测试,只是数字似乎是问题的根源。

Json 文档的文本文件大小约为 11 Mb - 我现在将尝试获取更相关的对象的实际大小。

我可以补充一点,在 mondoDb 日志文件中,只有当我尝试选择“超大”文档时才会出现一行:

2016-06-29T19:30:45.982+0200 I COMMAND  [conn12] command MYCOLLECTIONDb.$cmd command: aggregate 
 aggregate: "XXXX", pipeline: [  $match:  _id: "5773e0e9a1152d259c7d2e50"  ,  $limit: 1  ]
, cursor:   keyUpdates:0 writeConflicts:0 numYields:0 reslen:4188200 locks: Global:
  acquireCount:  r: 6  , MMAPV1Journal:  acquireCount: 
 r: 3  , Database:  acquireCount:  r: 3  , Collection:  acquireCount:  R: 3    109ms

(XXXX 是我的自定义对象)

所以我想知道您是否知道导致此问题的原因,是否有任何提示我应该尝试查看的位置,因为我已经没有想法了:)

EDIT_1:这基本上是我的对象的结构:

[DataContract]
public class MyClass

    [DataMember]
    public string _id  get; set; 

    [DataMember]
    public string XmlPreference  get; set; 

    [DataMember]
    public string XmlMarketDates  get; set; 

    [DataMember]
    public IEnumerable<ClassB> Lines  get; set; 


[DataContract]
public class ClassB

    [DataMember]
    public string UniqueId  get; set; 

    [DataMember]
    public string ParentId  get; set; 

    [DataMember]
    public Dictionary<string, ClassC> DataMapping get; set;

而 ClassC 只是一个包含 7 个整数和 1 个对象属性的容器。 还在找东西:)

编辑 2:我仅使用 mongoDb C# 驱动程序 2.1.1 发行版重现了该错误。这是代码:

using MongoDB.Bson;
using MongoDB.Driver.Linq;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace TestingMongoDbCsharpDriver

    class Program
    
        static void Main(string[] args)
        
            Console.WriteLine("Debugging starting...");

            try 
            
                MongoDB.Driver.MongoClient myClient = new MongoDB.Driver.MongoClient("mongodb://localhost:27010");
                var db = myClient.GetDatabase("DocumentStoreDb");
                var collection = db.GetCollection<DocumentModel>("TestOverload");

                Console.WriteLine("Collection TestOverload found");


                Random rand = new Random(999999999);
                DocumentModel toInsert = null;
                for (int lineNb = 1; lineNb < 50000; lineNb += 1000)
                
                    string id = rand.Next().ToString();
                    Console.WriteLine(string.Format("\nCreating document with id '0' and 1 lines...", id, lineNb));
                    toInsert = Funcs.Create(id, lineNb);
                    Console.WriteLine("Created.");

                    // Saving and waiting for it to finish
                    collection.InsertOneAsync(toInsert).Wait();
                    Console.WriteLine("Inserted.");

                    // retrieving it
                    var filter = new BsonDocument("_id", new BsonDocument("$eq", id));

                    var cursor = collection.FindAsync<DocumentModel>(filter).Result;                    
                    cursor.MoveNextAsync().Wait();
                    string messFilterMethod = cursor.Current.Count() == 1 ? "Retrieved" : "Not retrieved. Bug confirmed";
                    Console.WriteLine("With Filter: " + messFilterMethod);

                    var model = MongoQueryable.FirstOrDefaultAsync(collection.AsQueryable(), e => e._id == id).Result;
                    string mess = model != null ? "Retrieved" : "Not retrieved. Bug confirmed";
                    Console.WriteLine("With AsQueryable: " + mess);

                    // Removing it
                    collection.DeleteOneAsync(filter).Wait();
                    Console.WriteLine("Deleted.\n");

                    Console.ReadKey();
                
            
            catch (Exception e)
            
                Console.WriteLine("\n\nERROR: " + e.Message);
            
            Console.WriteLine("\n\n**************** NO BUG *************\n");
        

    


    public static class Funcs 
    
        public static DocumentModel Create(string uniqueId, int nbLines)
        
            Random random = new Random(2000000);
            List<MyDocumentSubElement> listOk = new List<MyDocumentSubElement>();

            for (int lines = 0; lines < nbLines; ++lines)
            
                Dictionary<string, SnapCellValueStyle> newDico = new Dictionary<string, SnapCellValueStyle>();
                for (int i = 0; i < 10; ++i)
                
                    int idSnap = random.Next();
                    var snap = new SnapCellValueStyle()
                    
                        alignment = idSnap,
                        Value = "okkkkkkkkkkzzzzkk"
                    ;
                    newDico.Add("newKey_" + idSnap.ToString(), snap);
                

                MyDocumentSubElement doc = new MyDocumentSubElement()
                
                    Icon = 516,
                    Name = "name du truc",
                    ParentId = "parent id",
                    type = SubElementType.T3,
                    UniqueId = "uniqueId_" + random.Next().ToString(),
                    MapColumnNameToCellValue = newDico
                ;
                listOk.Add(doc);
            

            int headerId = random.Next();
            MyDocumentHeader temp = new MyDocumentHeader()
            
                Comment = "comment",
                Date = DateTime.Now,
                ExtractionId = headerId,
                Id = "id ok _ " + headerId,
                Name = "Name really interesting name",
                OwnerId = 95115,
                RootFolioId = 51,
                SnapshotViewId = MyDocumentType.Type2
            ;

            DocumentModel toInsert = new DocumentModel()
            
                _id = uniqueId,
                Header = temp,
                XmlMarketDates = "<xmlPrefok65464f6szf65ze4f6d2f1ergers5fvefref3e4f05e4f064z68f4xd35f8eszf40s6e40f68z4f0e8511xf340ed53f1d51zf68d4z61ef644dcdce4f64zef84zOKok>><>>",
                XmlPreference = "<<zefaiunzhduiaopklzpdpakzdplapdergergfdgergekâzda4684z16ad84s2dd0486za04d68a04z8d0s1d d4az80d46az4d651s1d8 154efze40f6 4ze65f40 65ze40f6z4e>><>>>",
                Lines = listOk
            ;

            return toInsert;
          
    

    // Imitation of SnapshotDocModel
    [DataContract]
    public class DocumentModel
    
        [DataMember]
        public string _id  get; set; 

        [DataMember]
        public MyDocumentHeader Header  get; set; 

        [DataMember]
        public string XmlPreference  get; set; 

        [DataMember]
        public string XmlMarketDates  get; set; 

        [DataMember]
        public IEnumerable<MyDocumentSubElement> Lines  get; set; 
    

    [DataContract]
    public class MyDocumentHeader
    
        [DataMember]
        public string Id  get; set; 
        [DataMember]
        public string Name  get; set; 
        [DataMember]
        public int OwnerId  get; set; 
        [DataMember]
        public string Comment  get; set; 
        [DataMember]
        public DateTime Date  get; set; 
        [DataMember]
        public int RootFolioId  get; set; 
        [DataMember]
        public MyDocumentType SnapshotViewId  get; set; 
        [DataMember]
        public int ExtractionId  get; set; 
    

    [DataContract]
    public class MyDocumentSubElement
    
        [DataMember]
        public string UniqueId  get; set; 

        [DataMember]
        public string ParentId  get; set; 

        [DataMember]
        public int Icon  get; set; 

        [DataMember]
        public SubElementType type  get; set; 

        [DataMember]
        public Dictionary<string, SnapCellValueStyle> MapColumnNameToCellValue  get; set; 

        [DataMember]
        public string Name  get; set; 
    

    public class SnapCellValueStyle
    
        public object Value  get; set; 
        public int alignment  get; set; 
        public int Red  get; set; 
        public int Green  get; set; 
        public int Blue  get; set; 
        public int currency  get; set; 
        public int decimalPoint  get; set; 
        public int kind  get; set; 
        public int style  get; set; 
    

    #region enum
    public enum MyDocumentType
    
        Undefined,
        Type1,
        Type2,
        Type3,
        Type4,
        Type5
    

    public enum SubElementType
    
        T1,
        T2,
        T3
    
    #endregion

如果您对其进行测试,您将看到 AsQueryable 方法不再起作用的地方,因为使用过滤器的方法仍然可以检索文档。

【问题讨论】:

你能发布一个文档结构(准系统)吗?将尝试使用 2.2.4 驱动程序重现此情况 可能是这个错误:我不记得这个错误被击中所需的确切数字。请升级到 2.2.4,看看问题是否消失。 jira.mongodb.org/browse/CSHARP-1607 @profesor79 正如 Craig Wilson 所建议的那样,它可能与驱动程序版本有关。我会试试新的,看看效果如何!如果这不成功,我将发布我的课程的通用版本:) 我的虚拟类没有问题,我达到了 16767843 字节 嘿。所以...我还没有尝试 2.2.4 版本,因为我需要它签名。所以这可能需要更多时间:) 我真的希望它与@CraigWilson 错误有关。基本上,我的主干结构并没有那么复杂(我会更新问题,我正在测试同时希望找到一些东西) 【参考方案1】:

在 2.2.4 版本的 c# mongo db 驱动程序中修复了问题(可能带有错误 https://jira.mongodb.org/browse/CSHARP-1645)

谢谢:)

【讨论】:

以上是关于使用 C# Driver 2.1.1 存储在 MongoDb 集合中的对象的最大大小是多少?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中使用 IBM Informix ODBC Driver 查询问题

MongoDb GridFS的使用

MongoDB 3.2.9 关于安全认证后使用C#调用碰上的相关问题

如何使用 C# 在 WMI 中读取 ManagementObject 集合

MongoDb c# driver 2.0 查询样式

driver, module以及怎么看他们