Ого, это озадачивает. Очевидно, что здесь происходит какая-то ошибка округления.
> NumberLong("18014398509481984")-NumberLong("1");
18014398509481984
> NumberLong("18014398509481984")-NumberLong("2");
18014398509481982
> NumberLong("18014398509481984")+NumberLong("1");
18014398509481984
> NumberLong("18014398509481984")+NumberLong("2");
18014398509481984
> NumberLong("18014398509481984")+NumberLong("3");
18014398509481988
Возможно, это что-то не так с движком JavaScript, в котором работает оболочка, а не с самой MongoDB. Проверьте это, например - $inc
отлично работает:
> db.test.insert({twoTo54:NumberLong("18014398509481984")});
> db.test.update({},{$inc:{twoTo54:NumberLong("1")}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : NumberLong("18014398509481985") }
> db.test.update({},{$inc:{twoTo54:NumberLong("1")}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : NumberLong("18014398509481986") }
> db.test.update({},{$inc:{twoTo54:NumberLong("1")}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : NumberLong("18014398509481987") }
Вы должны быть осторожны, хотя. Если вы используете просто обычный литерал 1
, он преобразует тип в число, которое затем разбивает $inc
:
> db.test.update({},{$inc:{twoTo54:1}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : 18014398509481988 }
> db.test.update({},{$inc:{twoTo54:1}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : 18014398509481988 }
И даже если вы вернетесь к $inc
с NumberLong("1")
, оно все равно будет сломано:
> db.test.update({},{$inc:{twoTo54:NumberLong("1")}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : 18014398509481988 }
Определенно хорошо иметь в виду.