标签: mongodb-.net-driver

MongoDB性能问题:单个巨大集合与多个小集合

我测试了两个场景Single Huge collection vs Multiple Small Collections,并在查询时发现了巨大的性能差异.这就是我做的.

案例1:我创建了一个产品集合,其中包含10种不同类型产品的1000万条记录,并且每种产品类型的记录正好为100万条,我在ProductType上创建了索引.当我运行条件ProductType = 1和ProductPrice> 100并且限制(10)的示例查询返回ProductType = 1的10条记录并且其价格大于100时,当集合有很多产品价格时花了大约35毫秒当我们在ProductType = 1中的产品数量非常少而且价格大于100时,相同的查询大约需要8000毫秒(8秒).

案例2:我为每个ProductType创建了10个不同的Product表,每个ProductType包含100万条记录.在包含productType 1记录的集合1中,当我运行条件为ProductPrice> 100且limit(10)的相同样本查询返回10个价格大于100的产品记录时,当集合有很多时,它花了大约2.5毫秒价格超过100的产品,当价格大于100的产品数量非常少时,同样的查询大约需要1500毫秒(1.5秒).

那么为什么会有这么大的差异呢?案例一和案例二之间的唯一区别是一个巨大的集合与多个较小的集合,但我在第一个案例中创建了一个单一巨大集合的ProductType索引.我猜性能差异是由第一种情况下的索引引起的,我在第一种情况下需要该索引,否则性能会更差.我预计在第一种情况下由于指数会有一些表现缓慢但我没想到在第一种情况下差异大约10倍.

因此,对于一个巨大的集合与多个小集合相比,8000毫秒对1500毫秒.为什么?

mongodb mongodb-.net-driver

10
推荐指数
1
解决办法
7847
查看次数

查询的mongodb'count'非常慢

大家好,我使用mongodb 2.4.6版本和Windows 2008 64位版本.

我有一个有200万条记录的集合,需要在客户端进行搜索和分页.

db.products.find({"catalogs":1205}).skip().limit() is very fast .
Run Code Online (Sandbox Code Playgroud)

但是当计算总记录数时:

db.products.find({"catalogs":1205},{"_id":1}).count() is too slow.

>> 442312 records.

>>[log] Sat Sep 28 00:20:01.566 [conn10] command products.$cmd command: { count: "products", query: { catalogs: 1205.0 }, fields: { _id: 1.0 } } ntoreturn:1 keyUpdates:0 locks(micros) r:460681 reslen:48 460ms
Run Code Online (Sandbox Code Playgroud)

这个计数命令经过的时间是460ms,太慢了.如果我们有很多请求那么可怕.

我为'catalogs'字段创建了一个索引,并且无法使用$inc命令,因为查询可能非常复杂.

谷歌搜索一些像这个问题,发现这个'计数'性能错误已经修复mongodb 2.4版本.

来自http://docs.mongodb.org/manual/release-notes/2.4-overview/

Improvements to count provide dramatically faster count operations. Counting is now up to 20 times faster for low cardinality index based counts.
Run Code Online (Sandbox Code Playgroud)

有什么方法可以提高数量?谢谢. …

mongodb mongodb-.net-driver

10
推荐指数
1
解决办法
3870
查看次数

日期之间的MongoDB C#驱动程序聚合返回空字段

我正在使用mongodb的c#驱动程序,并希望对我正在创建的Web API使用聚合查询.对于我的聚合查询,我关注的是具有用户名,日期和步骤的配置文件类.我想创建一个查询,选择用户名并获取给定周的总步数,按总步数降序排列.我只想显示他们的用户名和他们的总步数.

当我尝试聚合查询时,我遇到了一些问题,我的某些字段将显示为null.所以,我认为我的查询结构不正确.

我有一个"配置文件"类,我目前用于我的数据.

[BsonIgnoreExtraElements]
[DataContract]
public class Profile 
{   
    [DataMember]
    public string Username { get; set; }

    [DataMember]
    public DateTime Date { get; set; }

    [DataMember]
    public uint? Steps { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我使用以下方法创建了一些测试数据,例如配置文件

//Test data
for (uint index = 1; index < 20; index++)
{      
    Profile aprofile = new Profile
    {   
        Username = string.Format("testuser{0}", index),
        Date = RandomDay(),
        Steps = (index + index + index)*2

    };
    AddProfile(aprofile);
}
Run Code Online (Sandbox Code Playgroud)

如果我运行代码几次并查询特定用户,我得到的数据如下:

[{"Username":"testuser1","Date":"2014-07-03T00:00:00Z","Steps":6},
{"Username":"testuser1","Date":"2014-07-07T05:00:00Z","Steps":6},
{"Username":"testuser1","Date":"2014-07-17T05:00:00Z","Steps":6},
{"Username":"testuser1","Date":"2014-07-18T05:00:00Z","Steps":6}]
Run Code Online (Sandbox Code Playgroud)

然后,我有几个静态方法来查找我的聚合查询的最早日期和最新日期.

//gets a datetime …
Run Code Online (Sandbox Code Playgroud)

c# mongodb aggregation-framework mongodb-.net-driver

10
推荐指数
1
解决办法
1694
查看次数

使用C#.NET驱动程序2.0投影mongodb子文档

我有以下结构:

public class Category
{
    [BsonElement("name")]
    public string CategoryName { get; set; }

    [BsonDateTimeOptions]
    [BsonElement("dateCreated")]
    public DateTime DateStamp { get; set; }

    [BsonElement("tasks")]        
    public List<TaskTracker.Task> Task { get; set; }
}

public class Task
{
    [BsonElement("name")]
    public string TaskName { get; set; }

    [BsonElement("body")]
    public string TaskBody { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我试图查询a Category以获取所有TaskName值,然后将它们返回到列表框中以显示.

我试过使用这个查询:

var getTasks = Categories.Find<Category>(x => x.CategoryName == catName)
                         .Project(Builders<Category>.Projection
                                                    .Include("tasks.name")
                                                    .Exclude("_id"))
                         .ToListAsync()
                         .Result;   
Run Code Online (Sandbox Code Playgroud)

但得到的回报是:{"tasks": [{"name: "test"}]}.

无论如何只返回字符串值?

.net c# mongodb mongodb-.net-driver

10
推荐指数
2
解决办法
2万
查看次数

MongoDB自定义序列化器实现

我是MongoDB的新手,我正在尝试让C#驱动程序工作序列化F#类.我使用可变F#字段和无参数构造函数使用类自动化程序,但实际上我需要保留不变性,所以我开始考虑实现IBsonSerializer来执行自定义序列化.我没有找到任何关于编写其中一个的文档,所以我们只是试图从驱动程序源代码中推断出来.

我遇到了一个问题,当在序列化程序上调用Deserialize方法时,CurrentBsonType被设置为EndOfDocument而不是我期待的开始.我在C#中编写了等效文件,以确保它不是一些F#怪异,但问题仍然存在.序列化部分似乎工作正常,可以从shell查询.以下是示例代码:

class Calendar {
    public string Id { get; private set; }
    public DateTime[] Holidays { get; private set; }

    public Calendar(string id, DateTime[] holidays) {
        Id = id;
        Holidays = holidays;
    }
}

class CalendarSerializer : BsonBaseSerializer {
    public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) {
        var calendar = (Calendar) value;
        bsonWriter.WriteStartDocument();
        bsonWriter.WriteString("_id", calendar.Id);
        bsonWriter.WriteName("holidays");
        var ser = new ArraySerializer<DateTime>();
        ser.Serialize(bsonWriter, typeof(DateTime[]), calendar.Holidays, null);
        bsonWriter.WriteEndDocument();
    }

    public override object Deserialize(BsonReader bsonReader, Type nominalType, Type …
Run Code Online (Sandbox Code Playgroud)

f# mongodb-.net-driver

9
推荐指数
1
解决办法
4536
查看次数

使用MongoDb csharp驱动程序更改类型时反序列化字段

我正在测试MongoDb的一些场景,以了解如何从可能的数据问题中恢复.

我有一个类(地址集合的地址)在地址中有一个zipcode属性,最初被转换为字符串.我保存了多个地址记录,可以很好地检索它们.像这样,var allAddresses = addresses.FindAllAs();

我将邮政编码属性更改为int并保存了一些记录.然后我将邮政编码属性更改回字符串.

当我尝试读取集合时,我得到了一个错误反序列化,正如预期的那样.var allAddresses = addresses.FindAllAs();

我的目标是能够覆盖反序列化,因此如果发生字段反序列化错误,我可以选择忽略它或应用默认值.

我尝试过自定义序列化程序,但它无法正常工作.任何建议,将不胜感激.

public class MyCustomSerializer : BsonBaseSerializer
  {

    public override object Deserialize(BsonReader bsonReader, Type nominalType,  IBsonSerializationOptions options)
    {
      if (bsonReader.CurrentBsonType != BsonType.String)
      {
        return string.Empty;
      }

      return bsonReader.ReadString();
    }

    public override void Serialize(
               BsonWriter bsonWriter,
               Type nominalType,
               object value,
               IBsonSerializationOptions options)
    {
      bsonWriter.WriteStartDocument();
      bsonWriter.WriteName("ZipCode");
      bsonWriter.WriteString(value.ToString());
      bsonWriter.WriteEndDocument();
    }
  }
Run Code Online (Sandbox Code Playgroud)

mongodb mongodb-.net-driver

9
推荐指数
1
解决办法
6310
查看次数

MongoDB C#驱动程序 - 如何使用Dictionary <string,string>列表插入

我是mongodb + C#驱动程序的新手,所以请原谅我的任何天真.

我正在尝试对一组键值对进行批量插入,因此我的数据结构是类型的List<Dictionary<string,string>>.

这是我的持久性代码示例:

public void Persist(string collectionName, List<Dictionary<string, string>> documents)
{
  string connectionString = ConfigurationManager.ConnectionStrings[CONNECTION_STRING_KEY].ConnectionString;
  MongoServer server = MongoServer.Create(connectionString);
  MongoCredentials credentials = new MongoCredentials("MYUser", "MyPassword");
  MongoDatabase myDb = server.GetDatabase("myDb", credentials);

  var collection = myDb .GetCollection(collectionName);

  using (server.RequestStart(myDb ))
  {
    var result = collection.InsertBatch(documents);
  }
}
Run Code Online (Sandbox Code Playgroud)

我收到有关序列化的错误:

MongoDB.Bson.BsonSerializationException:Serializer DictionarySerializer期望类型为DictionarySerializationOptions的序列化选项,而不是DocumentSerializationOptions.

我错过了设置吗?

编辑:更多信息

我的词典是我的实体.意思是,我只是将它们转储成一个,而不是创建一个保存属性的对象Dictionary.从mongo文档来看,它应该只是转换为mongo Document.

进一步编辑:扭曲问题

我可以通过将using语句更改为:来插入单个实例:

using (server.RequestStart(myDb))
  {
    foreach(var doc in documents)
      collection.Insert(new BsonDocument(doc));
    //var result = collection.InsertBatch(typeof(Dictionary<string, string>), documents);
  }
Run Code Online (Sandbox Code Playgroud)

但是,我关注的是性能,因为在真实情况下我会轻松拥有10k +词典.使用此代码,驱动程序是否足够智能批量处理这些代码?有没有办法保持InsertBatch但完成同样的事情?

当然,任何帮助都非常感谢.

c# serialization mongodb mongodb-.net-driver

9
推荐指数
1
解决办法
9349
查看次数

带有C#驱动程序2.0的MongoDB(服务器v 2.6.7):如何从InsertOneAsync获取结果

我正在使用C#驱动程序2.0测试MongoDB(服务器v 2.6.7).

当我使用插入函数存在InsertOneAsync一个_id存在的文档时,我期待一个像你从Mongo shell获得的错误:

WriteResult({
    "nInserted" : 0,
    "writeError" : {
            "code" : 11000,
            "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: mydb.Commands.$_id_  dup key: { : 0.0 }"
    }})
Run Code Online (Sandbox Code Playgroud)

但问题是带有C#驱动程序的插入不会抛出异常,我找不到WriteResult插入.当我查看数据库时,似乎什么都没发生.

所以我的问题是InsertOneAsync在插入现有内容时会发生_id什么?

Visual Studio中的代码:

IMongoCollection<BsonDocument> commandsCollection = db.GetCollection<BsonDocument>("Commands");
var bson = new BsonDocument
        {
            {"_id", i.Value},
            {"label", i.Key}
        };
commandsCollection.InsertOneAsync(bson);
Run Code Online (Sandbox Code Playgroud)

c# mongodb async-await mongodb-.net-driver

9
推荐指数
1
解决办法
7709
查看次数

在MongoDB C#中展开组聚合

我在使用新的C#2.0 MongoDB驱动程序和聚合管道时遇到了一些麻烦.

基本上,我试图返回对象上数组字段中最受欢迎的元素.字段类型是:IList<string> FavouritePlaceIds { get; set; }.

我有以下MongoDB聚合,它按预期工作:

db.users.aggregate([
    { $unwind : "$FavouritePlaceIds" },
    { $group: { "_id": "$FavouritePlaceIds", "count": {$sum: 1}}}, 
    { $sort : { "count": -1 }}
])
Run Code Online (Sandbox Code Playgroud)

但是,现在的问题是尝试使用新的MongoDB驱动程序2.0将其转换为C#代码.我一直在使用以下链接获取有关聚合管道的帮助:http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/crud/reading/#unwind

到目前为止,我已经为我的聚合管道提供了以下内容:

var pipeline = usersCollection.Aggregate()
                .Unwind(i => i.FavouritePlaceIds)
                .Group(i => i.FavouritePlaceIds, g => new { FavouritePlaceIds = g.Key, Count = g.Count() })
                .SortByDescending(i => i.Count);
Run Code Online (Sandbox Code Playgroud)

当我去编译该代码时,我得到以下消息:

'BsonDocument'不包含'FavouritePlaceIds'的定义,并且没有扩展方法'FavouritePlaceIds'接受类型'BsonDocument'的第一个参数可以找到...

i => i.FavouritePlaceIdsGroup()方法的第一个参数()发生错误.

阅读小组部分提供的链接上的笔记,它提到:

因为$ unwind是一种投影,所以必须提供返回类型.

所以,我假设我没有指定正确的返回类型,这就是为什么它期望一个BsonDocument对象,并且无法编译.

那么,如何指定要在Group方法中使用的正确返回类型?

c# mongodb mongodb-csharp-2.0 mongodb-.net-driver

9
推荐指数
1
解决办法
8419
查看次数

我如何使用Moq IFindFluent来调用ToListAsync?

我正在测试MongoDB C#驱动程序的包装器.我有这行代码:

Collection.Find(predicate).ToListAsync();
Run Code Online (Sandbox Code Playgroud)

where Collection类型IMongoCollection<T>Find(predicate)返回实现的实例IFindFluent<T, T>.ToListAsync()我假设是将结果转换为列表的扩展名.

我正在尝试编写单元测试,我很难处理这个问题.我不能创建一个包装类,因为这就是我正在做的事情.我宁愿让它成功,所以ToListAsync()返回一个创建的列表或模拟Find()返回可以作为列表的东西.

c# unit-testing moq mongodb-.net-driver

9
推荐指数
1
解决办法
1062
查看次数