(SQL) SQL (2016)

MongoDB - noSQL-database for irregular JSON data.

У 2016-му році я вперше познайомився з MongoDB і мені дуже сподобалось! Спочатку хочу трошки розповісти про ідею MongoDB. Загалом ідея цієї бази полягає в тому, щоб зберігати на діск іррегулярний JSON та відбирати з цього сховища JSON дещо по власним крітеріям.

Наприклад запис 3 має ось такий JSON, як на першому скріні, а дев'ятий JSON має вигляд, як на другому скріні. На ції скрінах можна дуже добре побачити, чим вдрізняються ці два JSON - перши має пустий об'єкт skills, а другий JSON maє skills з двох обьектів. Це не просто звичайна ієрархічна структура, а іррегулярна структура, кожен збереженний JSON може відрізнятися від попереднього. Третій та четверти скрини пояснюють це у текстовому та табличному вігляді.





Щоб працювати з MongoDB потрібно вирішити декілька питань. Перше питання - це інсталяція. Вона трівіальна.





Але для того, щоб запустити MongoDB у вигляді сервіса - потрібно дещо зробіти самостійно. Це нагадує запуск MySQL та PosgreSQL - потрібно зробити файлову структуру для бази, відкріти порти для сервіса та зробити конфіг сервіса, у якому буде вказано порти та шлях до бази на діскі.





У моєму випадку я зробив ось такий конфіг:



   1:  storage:
   2:      dbPath: c:\mongo\db\
   3:      mmapv1:
   4:          smallFiles: true
   5:      engine: mmapv1
   6:      journal:
   7:          enabled: true
   8:  systemLog:
   9:      destination: file
  10:      path: c:\mongo\log\log.txt
  11:  net:
  12:    port: 27017
  13:    bindIp: 127.0.0.1


Після ціх кроків сервіс стартовав:





Наступний дуже простий крок, необхідний щоб працювати з базою - це інсталяція GUI, що працює з двигуном бази. Я вибрав MongoVUE. Цей вибір нагадуе вибір MS SMS для MS SQL, MySQL Workbench для MS SQL, SQLAdmin для SQLLite та pgAdmin для PostgreSQL.





Наступний крок - це mongo-csharp-driver, який дозволяє працювати з базою програмно. Я записав усі зборки для роботі з MongoDB у той же самий каталог, де у мене зберігається база Mongo.





Наступний крок не має беспосереднього відношення до MongoDB, але без цього кроку працювати з JSON неможливо. Цей крок - інсталяція сборки Newtonsoft.JSON. І цю зборку, і зборку драйера MongoDB можливо інсталіровать беспосередньо із студіі за допомогою NUGET:





Ось тепер у нас є все, що необхідно для утворення проекту. Тільки потрібно без помилок зрозуміти версію NET, версію MongoDB, версію MongoCSharpDriver. У моєму середовище це виглядає ось так:





Взагалі зборки роботи з Mongo можна поставити і у GAC - це буде корисно, якщо ви маєте бажання вівчати мову запросів із MongoDB за допомогою LinqPAD.





I тепер ми дійшли до того стану, що вже можемо починати програмування з MongoDB. Взагалі тут багато чого можливо, мова запросів до бази з JSON достатньо продвинута, дивиться документацію на Mongo, тому я покажу тут лише невеличкий код, який зберігае в базу JSON, а потім вичітує JSON із бази, але парадігма роботи з діними JSON повинна бути зрозуміла з цього приклада.



   1:  Module Mongo
   2:   
   3:      Function ParseUpworkToMongoDB(Html As String) As Integer
   4:          Dim Pos1 As Integer = Html.IndexOf("var phpVars = {")
   5:          If Pos1 > 0 Then
   6:              Dim Pos2 As Integer = Html.IndexOf("}};", Pos1)
   7:              If Pos2 > 0 Then
   8:                  Dim Counters As String = Html.Substring(Pos1 + 14, Pos2 - Pos1 - 12)
   9:                  Dim JS As Newtonsoft.Json.Linq.JObject = Newtonsoft.Json.JsonConvert.DeserializeObject(Counters)
  10:                  Dim db1 As New ParserDBDataContext
  11:                  Dim MongoClient = New MongoDB.Driver.MongoClient("mongodb://localhost:27017/")
  12:                  Dim MongoServers As MongoDB.Driver.MongoServer = MongoClient.GetServer
  13:                  If MongoServers.Instances.Length > 0 Then
  14:                      Dim MNDB As MongoDB.Driver.MongoDatabase = MongoServers.GetDatabase("jobs")
  15:                      Dim Jobs = MNDB.GetCollection("Job")
  16:                      Dim I As Integer = 1
  17:                      For Each One In JS("jobs")
  18:                          Dim X As MongoDB.Bson.BsonDocument = MongoDB.Bson.BsonDocument.Parse(One.ToString)
  19:                          Jobs.Insert(X)
  20:                          I += 1
  21:                      Next
  22:                      Return I
  23:                  Else
  24:                      Return 0
  25:                  End If
  26:              Else
  27:                  Return 0
  28:              End If
  29:          Else
  30:              Return 0
  31:          End If
  32:      End Function


На цьому невеличкому фрагменті ви можете побачити, як я спочатку знайшов у HTML потрібний мені JSON (стрічка 1-8), який скаладається на кожній сторінці з декількох обьектів JOB. Потім я у стрічці 9 цей JSON за допомогою Newtonsoft.JSON перетворив на окремі обьекти JOB. У страчці 11 я зробив єкземпляр обьекту драйвера з коннектом. Зрозуміло, що більш гнучкий код потребує цей конект винести у конфиг, але у ціей програмі мені було цього достатньо. Потім у страчці 12-13 я подивився, чи пряцює двигун MongoDB - а якщо так, то у стрічці 14 отворив для роботи базу JOBS і зробив у неї колекцію JOB (аналог табли у SQL). Потім у стрічці 17 отримав черговий фрагмент JOB (а на моєї HTML-сторінці їх багато) і зберіг цей JSON у базу у стрічці 19. Перед тим отримавши у стрічці 18 спеціцічний обьект, який можливо збергати у базу Mongo.

Саме таким чином я отримав дані, які ви можете побачити на початку цієї сторінки.

А далі мені у ціей програмі були потрібні дані SKILL у вигляді SQL. Це я зробив ось таким кодом, який, мабуть, детально пояснювати вже не має сенсу, бо ви все вже зрозуміли.



  35:      Private Sub LoadSkillFromMongoDB()
  36:          Dim db1 As New ParserDBDataContext
  37:          Dim MongoClient = New MongoDB.Driver.MongoClient("mongodb://localhost:27017/")
  38:          Dim MongoServers As MongoDB.Driver.MongoServer = MongoClient.GetServer
  39:          If MongoServers.Instances.Length > 0 Then
  40:              Dim MNDB As MongoDB.Driver.MongoDatabase = MongoServers.GetDatabase("jobs")
  41:              Dim Jobs = MNDB.GetCollection("Job").FindAll
  42:              For Each One In Jobs
  43:                  'Debug.Print(One.ToString)
  44:                  If One.GetElement("skills") IsNot Nothing Then
  45:                      Dim OneVal = One.GetElement("skills")
  46:                      If OneVal.Value.IsBsonArray Then
  47:                          If OneVal.Value.ToString <> "[]" Then
  48:                              '"[{ "name" : ".net-framework", "prettyName" : ".NET Framework" }, { "name" : "salesforce-apex", "prettyName" : "Salesforce Apex" }, { "name" : "visualforce", "prettyName" : "visualforce" }]"
  49:                              Dim JS As Newtonsoft.Json.Linq.JArray = Newtonsoft.Json.JsonConvert.DeserializeObject(OneVal.Value.ToString)
  50:                              For Each X In JS
  51:                                  '"{    "name": ".net-framework",    "prettyName": ".NET Framework"  }"
  52:                                  'Debug.Print(X("prettyName").ToString)
  53:                                  'db1.Cats.InsertOnSubmit(New Cat With {.TXT = X("prettyName").ToString})
  54:                                  db1.SubmitChanges()
  55:                              Next
  56:   
  57:                          End If
  58:                      End If
  59:                  End If
  60:              Next
  61:          End If
  62:      End Sub
  63:  End Module


Саме таким чином я отримав лист з усіма спеціальностями програмистів, що мені був потрібен для подальшої обробки.





Далі я покажу ще один дуже цікавий приклад, коли використання MongoDB дуже корисно. У мене є свій відео-сервер, а також я деякі відео викладаю у Ютюб. Але як зробили перелік усіх моїх відео, щоб поріняти перелік відео на моєму сервері та на сервері Ютюба? І там і там відео дуже багато і руками дуже важко зробити цей перелік. Тому доведеться використати YouTube Data API.

Першим кроком, вводимо ID каналу у форму пошуку каналів https://developers.google.com/youtube/v3/docs/channels/list, наприклад UCDxUCKh5eNy9iYYm3Slydzw та параметр part=contentDetails. Ми повинні отримати перелік токенів, з яких нас буде цікавити токен Uploads.





Таким же чином можна отримати перелик плей-листів, для цього потрібно на формі https://developers.google.com/youtube/v3/docs/playlists/list задати channelId та part=contentDetails. А потім можна і отримати перелік усіх відео у кожному прей-листі.





Якщо нам потрібно отримати перелік усіх відео з описом, то беремо номер каналу Uploads (наприклад на моєму скріні це "UUDxUCKh5eNy9iYYm3Slydzw") і далі задаемо цей номер каналу для форми https://developers.google.com/youtube/v3/docs/playlistItems/list. Щоб отримати можливість задати всі параметри, замість першої сторінки даних, переходимо у Load in APIs Explorer. Там рухаємося по всім сторінкам, задаюч тег NextPage. Таким чином ми отримуємо перелік усіх відео по сторінкам, кожного разу задаючи новий номер сторінки.





А далі отримані описи відео ми зберігаємо в базу MongoDB:





А далі за допомогою такого ж шаблонногу коду, як і вище, я прочитав дані із MongoDB та переписав їх у реляційну базу (бо мій власний відео-сервер працює з реляційною базою і мені потрібно будо сінхронізувати дещо з відео).



   1:  Module Module1
   2:       Sub Main()
   3:          'SaveVideoList1()
   4:          'SaveVideoList2()
   5:          GetTable()
   6:      End Sub
   7:   
   8:      Sub GetTable()
   9:          Dim db1 As New YoutubeVideoDBDataContext
  10:          Dim V = (From X In db1.MyYoutubeVideos Select X Order By X.position).ToList
  11:          Dim T As New Text.StringBuilder("<table>")
  12:          For Each X In V
  13:              T.Append("<tr><td>")
  14:              T.Append(X.position.ToString)
  15:              T.Append("</td><td>")
  16:              T.Append(CDate(X.publishedAt).ToShortDateString)
  17:              T.Append("</td><td>")
  18:              T.Append(X.videoId)
  19:              T.Append("</td><td><a href='https://www.youtube.com/watch?v=")
  20:              T.Append(X.videoId)
  21:              T.Append("'>")
  22:              T.Append(X.title)
  23:              T.AppendLine("</a></td></tr>")
  24:          Next
  25:          T.Append("</table>")
  26:          My.Computer.FileSystem.WriteAllText("G:\Projects\YoutubeVideoList\YoutubeVideoList\Videotable.txt", T.ToString, False)
  27:      End Sub
  28:      Sub SaveVideoList2()
  29:          Dim db1 As New YoutubeVideoDBDataContext
  30:          Dim MongoClient = New MongoDB.Driver.MongoClient("mongodb://localhost:27017/")
  31:          Dim MongoServers As MongoDB.Driver.MongoServer = MongoClient.GetServer
  32:          If MongoServers.Instances.Length > 0 Then
  33:              Dim MNDB As MongoDB.Driver.MongoDatabase = MongoServers.GetDatabase("Youtube")
  34:              Dim Jobs = MNDB.GetCollection("PageList").FindAll
  35:              For Each One In Jobs
  36:                  If One.GetElement("items") IsNot Nothing Then
  37:                      Dim OneVal = One.GetElement("items")
  38:                      If OneVal.Value.IsBsonArray Then
  39:                          If OneVal.Value.ToString <> "[]" Then
  40:                              Dim JS As Newtonsoft.Json.Linq.JArray = Newtonsoft.Json.JsonConvert.DeserializeObject(OneVal.Value.ToString)
  41:                              For Each X In JS
  42:                                  Dim Y = New MyYoutubeVideo With {
  43:                                                                          .description = X.Item("snippet")("description").ToString,
  44:                                                                          .high_height = X.Item("snippet")("thumbnails")("high")("height").ToString,
  45:                                                                          .high_width = X.Item("snippet")("thumbnails")("high")("width").ToString,
  46:                                                                          .position = X.Item("snippet")("position").ToString,
  47:                                                                          .publishedAt = X.Item("snippet")("publishedAt").ToString,
  48:                                                                          .title = X.Item("snippet")("title").ToString,
  49:                                                                          .videoId = X.Item("snippet")("resourceId")("videoId").ToString
  50:                                                                  }
  51:                                  If X.Item("snippet")("thumbnails")("maxres") IsNot Nothing Then
  52:                                      Y.maxres_height = X.Item("snippet")("thumbnails")("maxres")("height").ToString
  53:                                      Y.maxres_width = X.Item("snippet")("thumbnails")("maxres")("width").ToString
  54:                                  End If
  55:                                  db1.MyYoutubeVideos.InsertOnSubmit(Y)
  56:                                  db1.SubmitChanges()
  57:                              Next
  58:                          End If
  59:                      End If
  60:                  End If
  61:              Next
  62:          End If
  63:      End Sub
  64:   
  65:      Sub SaveVideoList1()
  66:          Dim db1 As New YoutubeVideoDBDataContext
  67:          Dim MongoClient = New MongoDB.Driver.MongoClient("mongodb://localhost:27017/")
  68:          Dim MongoServers As MongoDB.Driver.MongoServer = MongoClient.GetServer
  69:          If MongoServers.Instances.Length > 0 Then
  70:              Dim MNDB As MongoDB.Driver.MongoDatabase = MongoServers.GetDatabase("Youtube")
  71:              Dim Jobs = MNDB.GetCollection("PlayList").FindAll
  72:              For Each One In Jobs
  73:                  If One.GetElement("items") IsNot Nothing Then
  74:                      Dim OneVal = One.GetElement("items")
  75:                      If OneVal.Value.IsBsonArray Then
  76:                          If OneVal.Value.ToString <> "[]" Then
  77:                              Dim JS As Newtonsoft.Json.Linq.JArray = Newtonsoft.Json.JsonConvert.DeserializeObject(OneVal.Value.ToString)
  78:                              For Each X In JS
  79:                                  db1.MyToutubeVideoLists.InsertOnSubmit(New MyToutubeVideoList With {.playlistId = X.Item("id")("playlistId").ToString, .title = X.Item("snippet")("title").ToString})
  80:                                  db1.SubmitChanges()
  81:                              Next
  82:                          End If
  83:                      End If
  84:                  End If
  85:              Next
  86:          End If
  87:      End Sub
  88:  End Module


Саме таким чином я отримав ось цю таблу, яку далі я почав сінхронізувати с відео на своєму власному мультікаст сервері.





Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19
Link to this page: http://www.vb-net.com/MongoDB/index.htm
<SITEMAP>  <MVC>  <ASP>  <NET>  <DATA>  <KIOSK>  <FLEX>  <SQL>  <NOTES>  <LINUX>  <MONO>  <FREEWARE>  <DOCS>  <ENG>  <MAIL ME>  <ABOUT ME>  < THANKS ME>