阻止mongoDB中的更改字段

时间:2013-08-22 18:08:50

标签: mongodb mongodb-.net-driver mongodb-scala

我在MongoDB中有一个增加的集合,该字段最初被定义为一个整数,但我发现在增加之后转换为double。

但随后我对文档进行了更新,并看到对Long的更改。

有没有办法阻止Mongo中的这些变化?

提前致谢

2 个答案:

答案 0 :(得分:1)

MongoDB是无架构的。 Schamalessness可以更轻松地更改数据结构,但代价是数据库不强制执行类型约束等操作。您需要在应用程序代码中遵守规则,以确保按照您希望的方式保留事物。

如果您需要确保数据始终是Integer类型,那么建议您的应用程序通过应用程序中的数据访问层访问MongoDB。数据访问层可以强制执行类型约束(以及您希望放在对象上的任何其他约束)。

简短回答:没有办法在MongoDB中强制执行此操作。

答案 1 :(得分:1)

由于MongoDB每个集合没有固定的模式,因此无法阻止数据库端的此类更改。确保您在任何地方使用相同的数据类型,包括其更新操作。 C#驱动程序非常聪明。

使用外壳时要小心,它可能会有刺激性。默认情况下,mongo shell会将每个数字视为double,例如:

> db.Inc.find().pretty();
{ "_id" : 1, "Number" : 1000023272226647000 }
// this number is waaayyy larger than the largest 32 bit int, but there's no
// NumberLong here. So it must be double.
> db.Inc.update({}, {$inc: {"Number" : 1 }});
> db.Inc.find().pretty();
{ "_id" : 1, "Number" : 1000023272226647000 }
// Yikes, the $inc doesn't work anymore because of precision loss

让我们使用NumberLong

> db.Inc.insert({"Number" : NumberLong("1000023272226647000")});
> db.Inc.update({}, {$inc: {"Number" : 1}});
> db.Inc.find();
{ "Number" : 1000023272226647000, "_id" : 1 }
// Yikes! type conversion changed to double again! Also note 
// that the _id field moved to the end

我们也在NumberLong中使用$inc

> db.Inc.insert({"Number" : NumberLong("1000023272226647000")});
> db.Inc.update({}, {$inc: {"Number" : NumberLong("1")}});
> db.Inc.find();
{ "_id" : 1, "Number" : NumberLong("1000023272226647001") }
// This actually worked

在C#中,以下两个更新都有效,Number仍然很长:

class Counter { public long Number {get;set;} public ObjectId Id {get;set;} }
var collection = db.GetCollection("Counter");
collection.Insert(new Counter { Number = 1234 }); 
collection.Update(Query.Null, Update<Counter>.Inc(p => p.Number, 1)); // works
collection.Update(Query.Null, Update.Inc("Number", 1)); // works too