简体   繁体   English

阻止mongoDB中的更改字段

[英]Block a change field in mongoDB

I have a collection in MongoDB which makes an increase, the field was initially defined as an Integer, but I find that after the increase was converted to double. 我在MongoDB中有一个集合,它增加了,该字段最初被定义为一个整数,但我发现在增加之后转换为double。

But then I make an update of the document and see that changes to Long. 但后来我对文档进行了更新,看到对Long的更改。

Is there any way to block these changes in Mongo? 有没有办法阻止Mongo中的这些变化?

Thanks in advance 提前致谢

MongoDB is schema-less. MongoDB是无架构的。 Schamalessness provides for easier changes in your data structure but at the cost of the database not enforcing things like type constraints. Schamalessness可以更轻松地更改数据结构,但代价是数据库不强制执行类型约束等操作。 You need to be disciplined in your application code to ensure that things are persisted in the way you want them to be. 您需要在应用程序代码中遵守规则,以确保按照您希望的方式保留事物。

If you need to ensure that the data is always of type Integer then it's recommended to have your application access MongoDB through a data access layer within the application. 如果您需要确保数据始终是Integer类型,那么建议您的应用程序通过应用程序中的数据访问层访问MongoDB。 The data access layer can enforce type constraints (as well as any other constraints you want to put on your objects). 数据访问层可以强制执行类型约束(以及您希望放在对象上的任何其他约束)。

Short answer: There is no way to enforce this in MongoDB. 简短回答:没有办法在MongoDB中强制执行此操作。

Since MongoDB doesn't have a fixed schema per collection, there's no way to prevent such changes on the database side. 由于MongoDB每个集合没有固定的模式,因此无法在数据库端阻止此类更改。 Make sure that you use the same data type for the field everywhere, including its update operations. 确保您在任何地方使用相同的数据类型,包括其更新操作。 The C# driver is pretty smart about this. C#驱动程序非常聪明。

Be careful when working with the shell, it can be irritating. 使用外壳时要小心,它可能会有刺激性。 Per default, the mongo shell will treat every number as a double , eg: 默认情况下,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

Let's use NumberLong : 我们来使用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

Let's use NumberLong also in $inc : 让我们在$inc使用NumberLong

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

In C#, both of the following updates work, Number remains a long: 在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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM