MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Въведение в типовете данни на MongoDB


Въведение

Когато използвате MongoDB, имате възможността да бъдете гъвкави със структурата на вашите данни. Не сте принудени да поддържате определена схема, в която трябва да се поберат всичките ви документи. За всяко дадено поле в документ можете да използвате всеки от наличните типове данни поддържан от MongoDB. Въпреки този начин на работа по подразбиране, вие можете да наложите JSON схема в MongoDB, за да добавите валидиране на вашите колекции, ако желаете. Няма да навлизаме в подробности за дизайна на схемата в това ръководство, но това може да има ефект върху въвеждането на данни, ако бъде внедрено.

Типовете данни определят общ модел за данните, които приемат и съхраняват. От първостепенно значение е да разберете кога да изберете определен тип данни пред друг, когато планирате вашата база данни. Избраният тип ще диктува как можете да работите с вашите данни и как те се съхраняват.



JSON и BSON

Преди да навлезете в подробности за конкретни типове данни, важно е да разберете как MongoDB съхранява данни. MongoDB и много други базирани на документи NoSQL бази данни използват JSON (JavaScript Object Notation) за представяне на записи от данни като документи.

Използването на JSON за съхранение на данни има много предимства. Някои от тях са:

  • лесна за четене, учене и познаване сред разработчиците
  • гъвкавост във формата, независимо дали е рядък, йерархичен или дълбоко вложен
  • самоописващ се, което позволява на приложенията лесно да работят с JSON данни
  • позволява фокусиране върху минимален брой основни типове

JSON поддържа всички основни типове данни като низ, число, булеви и т.н. MongoDB всъщност съхранява записи от данни като двоично кодирани JSON (BSON) документи. Подобно на JSON, BSON поддържа вграждането на документи и масиви в други документи и масиви. BSON позволява допълнителни типове данни, които не са достъпни за JSON.



Какви са типовете данни в MongoDB?

Преди да влезем в подробности, нека разгледаме по-широко какви типове данни се поддържат в MongoDB.

MongoDB поддържа редица типове данни, подходящи за различни типове прости и сложни данни. Те включват:

Текст

  • String

Цифрови

  • 32-Bit Integer
  • 64-Bit Integer
  • Double
  • Decimal128

Дата/Час

  • Date
  • Timestamp

Друго

  • Object
  • Array
  • Binary Data
  • ObjectId
  • Boolean
  • Null
  • Regular Expression
  • JavaScript
  • Min Key
  • Max Key

В MongoDB всеки тип BSON има както цяло число, така и низови идентификатори. Ще разгледаме най-често срещаните от тях по-задълбочено в това ръководство.



Типове низове

Типът низ е най-често използваният тип данни на MongoDB. Всяка стойност, написана в двойни кавички "" в JSON е низова стойност. Всяка стойност, която искате да бъде съхранена като текст, ще бъде най-добре да бъде въведена като String . BSON низовете са UTF-8 и са представени в MongoDB като:

        Type         | Number |  Alias   |  ------------------ | ------ | -------- |       String        |    2   | "string" |

По принцип драйверите за езици за програмиране ще конвертират от низовия формат на езика в UTF-8 при сериализиране и десериализиране на BSON. Това прави BSON атрактивен метод за лесно съхранение на международни знаци, например.

Вмъкване на документ с String тип данни ще изглежда така:

db.mytestcoll.insertOne({first_name: "Alex"}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d15")}

Запитването на колекцията ще върне следното:

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d15"),         first_name: "Alex"}

Използване на $type оператор

Преди да преминете към следващия ни тип данни, важно е да знаете как можете да въведете проверете стойността, преди да правите каквото и да е вмъкване. Ще използваме предишния пример, за да демонстрираме използването на $type оператор в MongoDB.

Да кажем, че е минало известно време, откакто работихме с mytestcoll колекция от преди. Искаме да вмъкнем някои допълнителни документи в колекцията с first_name поле. За да проверим дали използвахме String като тип данни, съхранен като стойност на first_name първоначално можем да изпълним следното, като използваме псевдоним или числова стойност на типа данни:

db.mytestcoll.find( { "first_name": { $type: "string" } } )

Или

db.mytestcoll.find( { "first_name": { $type: 2 } } )

И двете заявки връщат изход от всички документи, които имат String стойност, съхранена за first_name от вмъкването на предишния ни раздел:

[ { _id: ObjectId("614b37296a124db40ae74d15"), first_name: "Alex" } ]

Ако заявите за тип, който не се съхранява в first_name поле на всеки документ, няма да получите резултат. Това показва, че това е друг тип данни, съхранен в first_name .

Можете също така да правите заявки за няколко типа данни едновременно с $type оператор като следния:

db.mytestcoll.find( { "first_name": { $type: ["string", "null"] } } )

Тъй като не вмъкнахме никакъв Null въведете стойности в нашата колекция, резултатът ще бъде същият:

[ { _id: ObjectId("614b37296a124db40ae74d15"), first_name: "Alex" } ]

Можете да използвате същия метод с всички от следните типове, които ще обсъдим.




Числа и числови стойности

MongoDB включва набор от числови типове данни, подходящи за различни сценарии. Решаването кой тип да използвате зависи от естеството на стойностите, които планирате да съхранявате, и вашите случаи на използване на данните. JSON извиква всичко с числа Число . Това принуждава системата да разбере как да я превърне в най-близкия роден тип данни. Ще започнем с изследване на цели числа и как те работят в MongoDB.


Цяло число

Integer типът данни се използва за съхраняване на числа като цели числа без никакви дроби или десетични знаци. Целите числа могат да бъдат както положителни, така и отрицателни стойности. Има два типа в MongoDB, 32-Bit Integer и 64-Bit Integer . Те могат да бъдат представени по двата начина, описани в таблицата по-долу, number и alias :

  Integer type   | number |    alias     |   ------------   | -----  | ------------ |  `32-bit integer`|   16   |    "int"     | `64-bit integer`|   18   |    "long"    |

Диапазоните, в които една стойност може да се побере за всеки тип, са следните:

  Integer type   |    Applicable signed range     |    Applicable unsigned range    |  ------------   | ------------------------------ | ------------------------------- | `32-bit integer`| -2,147,483,648 to 2,147,483,647|  0 to 4,294,967,295             | `64-bit integer`| -9,223,372,036,854,775,808 to  |  0 to 18,446,744,073,709,551,615                         9,223,372,036,854,775,807

Горните типове са ограничени от техния валиден обхват. Всяка стойност извън диапазона ще доведе до грешка. Вмъкване на Integer Въведете в MongoDB ще изглежда по-долу:

db.mytestcoll.insertOne({age: 26}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d14")}

И намирането на резултата ще върне следното:

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d14"), age: 26}

Както подсказват имената, 32-Bit Integer има 32 бита целочислена прецизност, което е полезно за по-малки цели числа, които не искате да съхранявате като последователност от цифри. Когато увеличавате размера на числата, можете да достигнете до 64-Bit Integer който има 64 бита целочислена точност и отговаря на същия случай на употреба като предишния.



Двойно

В BSON, заместването по подразбиране за Номер на JSON е Double тип данни. Double типът данни се използва за съхраняване на стойност с плаваща запетая и може да бъде представен в MongoDB така:

        Type         | Number |   Alias  |  ------------------ | ------ | -------- |       Double        |    1   | "double" |

Числата с плаваща запетая са друг начин за изразяване на десетични числа, но без точна, последователна точност.

Числата с плаваща запетая могат да работят с голям брой десетични знаци ефективно, но не винаги точно. Следва пример за въвеждане на документ с Double въведете в колекцията си:

db.mytestcoll.insertOne({testScore: 89.6}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d13")}

Може да има леки разлики между входа и изхода при изчисляване с удвояване, което потенциално може да доведе до неочаквано поведение. При извършване на операции, които изискват точни стойности, MongoDB има по-точен тип.



Decimal128

Ако работите с много големи числа с много диапазон с плаваща запетая, тогава Decimal128 Типът данни BSON ще бъде най-добрият вариант. Това ще бъде най-полезният тип за стойности, които изискват много прецизност, както в случаи на използване, включващи точни парични операции. Decimal128 типът е представен като:

        Type         | Number |   Alias   |  ------------------ | ------ | --------- |      Decimal128     |   19   | "decimal" |

Типът BSON, Decimal128 , предоставя 128 бита десетично представяне за съхранение на числа, където точното закръгляване на десетичните знаци е важно. Decimal128 поддържа 34 десетични цифри с точност или синификанд с диапазон от -6143 до +6144. Това позволява висока прецизност.

Вмъкване на стойност с помощта на Decimal128 типът данни изисква използването на NumberDecimal() конструктор с вашия номер като String за да предпазите MongoDB от използването на цифровия тип по подразбиране, Double .

Ето, ние демонстрираме това:

db.mytestcoll.insertOne({price : NumberDecimal("5.099")}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d12")}

Когато правите заявка за колекцията, получавате следното връщане:

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d12"),         price: "5.099" }

Числовата стойност поддържа своята прецизност, позволявайки точни операции. За да демонстрирате Decimal128 тип срещу Double , можем да преминем през следното упражнение.



Как може да се загуби прецизността въз основа на типа данни

Да кажем, че искаме да вмъкнем число с много десетични стойности като Double в MongoDB със следното:

db.mytestcoll.insertOne({ price: 9999999.4999999999 }){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d24")}

Когато потърсим тези данни, получаваме следния резултат:

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d24"),         price: 9999999.5}

Тази стойност се закръгля до 9999999.5 , губейки точната си стойност, с която сме го въвели. Това прави Double неподходящ за съхранение на числа с много десетични знаци.

Следващият пример демонстрира къде ще се загуби прецизността при подаване на Double имплицитно с Decimal128 вместо String като в предишния пример.

Започваме с вмъкване на следния Double отново, но с NumberDecimal() за да го направите Decimal128 тип:

db.mytestcoll.insertOne({ price: NumberDecimal( 9999999.4999999999 ) }){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d14")}

Забележка :Когато правите това вмъкване в обвивката на MongoDB, се показва следното предупредително съобщение:

Warning: NumberDecimal: specifying a number as argument is deprecated and may lead to loss of precision, pass a string instead

Това предупредително съобщение показва, че номерът, който се опитвате да преминете, може да бъде обект на загуба на точност. Те предлагат да се използва String използвайки NumberDecimal() така че да не губите никаква прецизност.

Ако игнорираме предупреждението и все пак вмъкнем документа, загубата на прецизност се вижда в резултата на заявката от закръгляването на стойността:

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d14"),         price: Decimal128("9999999.50000000")}

Ако следваме препоръчания NumberDecimal() подход с помощта на String ще видим следните резултати с поддържана точност:

db.mytestcoll.insertOne({ price: NumberDecimal( "9999999.4999999999" ) } )
db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d14"),         price: Decimal128("9999999.4999999999")}

За всеки случай на употреба, изискващ точни, точни стойности, това връщане може да причини проблеми. Всяка работа, включваща парични операции, е пример, при който прецизността ще бъде изключително важна и наличието на точни стойности е от решаващо значение за точните изчисления. Тази демонстрация подчертава колко е важно да знаете кой числов тип данни ще бъде най-подходящ за вашите данни.




Дата

BSON Date Типът данни е 64-битово цяло число, което представлява броя милисекунди от епохата на Unix (1 януари 1970 г.). Този тип данни съхранява текущата дата или час и може да бъде върнат като обект за дата или като низ. Date е представен в MongoDB, както следва:

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |        Date         |    9   |     "date"   |

Забележка :BSON Date типът е подписан. Отрицателните стойности представляват дати преди 1970 г.

Има три метода за връщане на стойности за дата.

  1. Date() - връща низ

  2. new Date() - връща обект за дата с помощта на ISODate() обвивка

  3. ISODate() - също връща обект за дата с помощта на ISODate() обвивка

По-долу демонстрираме тези опции:

var date1 = Date()var date2 = new Date()var date3 = ISODate()db.mytestcoll.insertOne({firstDate: date1, secondDate: date2, thirdDate: date3}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d22")}

И при връщане:

db.mytestcoll.find().pretty(){                "_id" : ObjectId("614b37296a124db40ae74d22"),                firstDate: 'Tue Sep 28 2021 11:28:52 GMT+0200 (Central European Summer Time)',                secondDate: ISODate("2021-09-28T09:29:01.924Z"),                thirdDate: ISODate("2021-09-28T09:29:12.151Z")}


Timestamp

Има и Timestamp тип данни в MongoDB за представяне на времето. Въпреки това, Timestamp ще бъде най-полезен за вътрешна употреба ине свързана с Date Тип. Самият тип е поредица от знаци, използвани за описване на датата и часа, когато настъпи събитие. Timestamp е 64-битова стойност, където:

  • най-значимите 32 бита са time_t стойност (секунди от епохата на Unix)
  • най-малко значимите 32 бита са нарастващ ordinal за операции в рамките на дадена секунда

Представянето му в MongoDB ще изглежда по следния начин:

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |      Timestamp      |   17   |  "timestamp" |

Когато вмъквате документ, който съдържа полета от най-високо ниво с празни времеви печати, MongoDB ще замени празната стойност на времеви печат с текущата стойност на времеви печат. Изключение от това е, ако _id полето съдържа празна времева марка. Стойността на клеймото за време винаги ще се вмъква както е и не се заменя.

Вмъкване на нов Timestamp стойност в MongoDB ще използва new Timestamp() функция и изглежда така:

db.mytestcoll.insertOne( {ts: new Timestamp() });{        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d23")}

Когато правите заявка за колекцията, ще върнете резултат, наподобяващ:

db.mytestcoll.find().pretty(){        "_id" : ObjectId("614b37296a124db40ae74d24"),         "ts" : Timestamp( { t: 1412180887, i: 1 })}


Обект

Object типът данни в MongoDB се използва за съхранение на вградени документи. Вграденият документ е поредица от вложени документи в key: value формат на двойки. Ние демонстрираме Object въведете по-долу:

var classGrades = {"Physics": 88, "German": 92, "LitTheoery": 79}db.mytestcoll.insertOne({student_name: "John Smith", report_card: classGrades}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d18")}

След това можем да видим нашия нов документ:

db.mytestcoll.find().pretty(){    _id: ObjectId("614b37296a124db40ae74d18"),    student_name: 'John Smith',    report_card: {Physics: 88, German: 92, LitTheoery: 79}}

Object типът данни оптимизира за съхранение на данни, които са най-добре достъпни заедно. Той осигурява известна ефективност по отношение на съхранението, скоростта и издръжливостта, за разлика от съхраняването на всеки знак за клас, от горния пример, отделно.



Двоични данни

Binary Data или BinData , типът данни прави точно това, което предполага името му и съхранява двоични данни за стойността на полето. BinData се използва най-добре, когато съхранявате и търсите данни, поради неговата ефективност при представяне на битови масиви. Този тип данни може да бъде представен по следните начини:

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |      Binary data    |    5   |   "binData"  |

Ето пример за добавяне на някои Binary Data в документ в колекция:

var data = BinData(1, "111010110111100110100010101")db.mytestcoll.insertOne({binaryData: data}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d20")}

За да видите след това получения документ:

db.mytestcoll.find().pretty(){        "_id" : ObjectId("614b37296a124db40ae74d20"),        "binaryData" : BinData(1, "111010110111100110100010101")}


ObjectId

ObjectId Типът е специфичен за MongoDB и съхранява уникалния идентификатор на документа. MongoDB предоставя _id поле за всеки документ. ObjectId е с размер 12 байта и може да бъде представен по следния начин:

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |      ObjectId       |    7   |   "objectId" |

ObjectId се състои от три части, които съставляват неговия 12-байтов състав:

  • 4-байтова стойност на времевия клей , представляващо създаването на ObjectId, измерено в секунди от епохата на Unix
  • 5-байтова случайна стойност
  • 3-байтов нарастващ брояч инициализира се на произволна стойност

В MongoDB всеки документ в колекция изисква уникален _id да действа като първичен ключ. Ако _id полето остава празно за вмъкнат документ, MongoDB автоматично ще генерира ObjectId за полето.

Има няколко предимства от използването на ObjectIds за _id :

  • на mongosh (MongoDB shell), времето за създаване на ObjectId е достъпен с помощта на ObjectId.getTimestamp() метод.
  • сортиране по _id поле, което съхранява ObjectId типовете данни е близък еквивалент на сортирането по време на създаване.

Виждали сме ObjectIds в примерите досега и те ще изглеждат подобно на това:

db.mytestcoll.find().pretty(){         _id: ObjectId("614b37296a124db40ae74d19")}

Забележка :Стойностите на ObjectId трябва да се увеличават с времето, но те не са непременно монотонни. Това е така, защото те:

  • Съдържат само една секунда времева разделителна способност, така че стойностите, създадени в рамките на една и съща секунда, нямат гарантирано подреждане
  • Стойностите се генерират от клиенти, които може да имат различни системни часовници


Булев

MongoDB има родния Boolean тип данни за съхраняване на истинни и неверни стойности в колекция. Boolean в MongoDB може да бъде представен по следния начин:

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |       Boolean       |    8   |     "bool"   |

Вмъкване на документ с Boolean тип данни ще изглежда по следния начин:

db.mytestcoll.insertOne({isCorrect: true, isIncorrect: false}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d21")}

След това при търсене на документа резултатът ще се появи като:

db.mytestcoll.find().pretty(){    "_id" : ObjectId("614b37296a124db40ae74d21")    "isCorrect" : true,    "isIncorrect" : false}


Регулярен израз

Regular Expression типът данни в MongoDB позволява съхранението на регулярни изрази като стойност на поле. MongoDB използва PCRE (Perl Compatible Regular Expression) като език за регулярни изрази.

Тя може да бъде представена по следния начин:

        Type         | Number |  Alias  |  ------------------ | ------ | ------- |  Regular Expression |   11   | "regex" |

BSON ви позволява да избегнете типичната стъпка "преобразуване от низ", която обикновено се среща при работа с регулярни изрази и бази данни. Този тип ще бъде най-полезен, когато пишете обекти на база данни, които изискват модели за валидиране или съвпадащи тригери.

Например, можете да вмъкнете Regular Expression тип данни като този:

db.mytestcoll.insertOne({exampleregex: /tt/}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d16")}db.mytestcoll.insertOne({exampleregext:/t+/}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d17")}

Тази последователност от изявления ще добави тези документи към вашата колекция. След това можете да направите заявка за вашата колекция, за да намерите вмъкнатите документи:

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d16"), exampleregex: /tt/,        _id: ObjectId("614b37296a124db40ae74d17"), exampleregex: /t+/ }

Шаблоните на регулярните изрази се съхраняват като регулярен израз, а не като низове. Това ви позволява да направите заявка за конкретен низ и да получите върнати документи, които имат регулярен израз, съответстващ на желания низ.



JavaScript (без обхват)

Подобно на по-горе споменатия Regular Expression тип данни, BSON позволява на MongoDB да съхранява JavaScript функции без обхват като свой собствен тип. JavaScript тип може да бъде разпознат, както следва:

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |      JavaScript     |   13   | "javascript" |

Добавяне на документ към вашата колекция с JavaScript тип данни ще изглежда така:

db.mytestcoll.insertOne({jsCode: "function(){var x; x=1}"}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d122")}

Тази функционалност ви позволява да съхранявате JavaScript функции във вашите MongoDB колекции, ако е необходимо за конкретен случай на употреба.

Забележка :С MongoDB версия 4.4 и по-нова, алтернативен тип JavaScript, JavaScript with Scope тип данни, е отхвърлен



Заключение

В тази статия разгледахме повечето от често срещаните типове данни, които са полезни при работа с бази данни MongoDB. Има допълнителни типове, които не са изрично обхванати в това ръководство, които може да са полезни в зависимост от случая на употреба. Първите стъпки с познаването на тези типове обхваща повечето случаи на употреба. Това е силна основа да започнете да моделирате вашата база данни MongoDB.

Важно е да знаете какви типове данни са достъпни за вас, когато използвате база данни, така че да използвате валидни стойности и да работите с данните с очаквани резултати. Има рискове, на които можете да се сблъскате, без да въвеждате правилно данните си, както е показано в Double спрямо Decimal128 упражнение. Важно е да помислите за това, преди да се ангажирате с даден тип.

Ако се интересувате да проверите Prisma с база данни MongoDB, можете да разгледате документацията на конектора за данни.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как да намерите подниз в поле в Mongodb

  2. как да управлявате полето _id, когато използвате POCO с mongodb c# драйвер

  3. Изграждане на REST API с помощта на EVE

  4. mongo групова заявка как да запазите полета

  5. Създайте многоезичен текстов индекс в MongoDB