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

$unionWith – Еквивалент на MongoDB на UNION ALL

Ако сте запознати с SQL, може да знаете за UNION клауза, която обединява резултатите от две заявки в един набор от резултати. По-специално UNION ALL включва дубликати.

В MongoDB можем да използваме $unionWith етап на тръбопровод на агрегация за постигане на същия ефект като UNION ALL произвежда. $unionWith stage изпълнява обединение на две колекции – комбинира резултатите от конвейера от две колекции в един набор от резултати. И включва дубликати.

Пример

Да предположим, че създаваме две колекции; един, наречен cats и друг, наречен dogs . И вмъкваме в тях следните документи:

db.cats.insertMany([
    { _id: 1, name: "Fluffy", type: "Cat", weight: 5 },
    { _id: 2, name: "Scratch", type: "Cat", weight: 3 },
    { _id: 3, name: "Meow", type: "Cat", weight: 7 }
    ])

db.dogs.insertMany([
    { _id: 1, name: "Wag", type: "Dog", weight: 20 },
    { _id: 2, name: "Bark", type: "Dog", weight: 10 },
    { _id: 3, name: "Fluffy", type: "Dog", weight: 40 }
    ]) 

Вече можем да изпълняваме заявки към тези колекции и да използваме $unionWith етап за комбиниране на резултатите от всяка заявка.

Пример:

db.cats.aggregate( [
   { $set: { _id: "$_id" } },
   { $unionWith: { coll: "dogs", pipeline: [ { $set: { _id: "$_id" } } ] } },
   { $sort: { type: 1, weight: -1, name: 1 } }
] ) 

Резултат:

{ "_id" :3, "name" :"Meow", "type" :"Cat", "weight" :7 }{ "_id" :1, "name" :"Fluffy", "type" :"Cat", "weight" :5 }{ "_id" :2, "name" :"Scratch", "type" :"Cat", "weight" :3 }{ "_id" :3, "name" :"Пухкав", "тип" :"Куче", "тегло" :40 }{ "_id" :1, "име" :"Размахване", "тип" :"Куче", "тегло" :20 }{ " _id" :2, "name" :"Лая", "тип" :"Куче", "тегло" :10 }

В този пример всеки документ има поле за тип с cat или dog и така е съвсем очевидно кой документ от коя колекция идва.

Но ако документите нямат полето за тип, тогава би било по-трудно да се разбере къде завършва една колекция и започва друга. В този случай можем да използваме низов литерал в $set етап за представяне на името на колекцията.

Пример:

db.cats.aggregate( [
   { $set: { _id: "cat" } },
   { $unionWith: { coll: "dogs", pipeline: [ { $set: { _id: "dog" } } ] } },
   { $sort: { type: 1, weight: -1, name: 1 } }
] ) 

Резултат:

{ "_id" :"cat", "name" :"Meow", "type" :"Cat", "weight" :7 }{ "_id" :"cat", "name" :"Puffy" , "type" :"Cat", "weight" :5 }{ "_id" :"cat", "name" :"Scratch", "type" :"Cat", "weight" :3 }{ "_id" :"куче", "име" :"Пухкаво", "тип" :"Куче", "тегло" :40 }{ "_id" :"куче", "име" :"Размахване", "тип" :"Куче ", "тегло" :20 }{ "_id" :"куче", "име" :"Ла", "тип" :"Куче", "тегло" :10 }

Сортиране в колекции

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

Но можем да го сортираме във всяко друго поле, което може да доведе до комбиниране на котки и кучета.

Пример:

db.cats.aggregate( [
   { $set: { _id: "cat" } },
   { $unionWith: { coll: "dogs", pipeline: [ { $set: { _id: "dog" } } ] } },
   { $sort: { name: 1 } }
] ) 

Резултат:

{ "_id" :"куче", "name" :"Лая", "тип" :"Куче", "тегло" :10 }{ "_id" :"котка", "име" :"Пухкав" , "тип" :"Котка", "тегло" :5 }{ "_id" :"куче", "име" :"Пухкаво", "тип" :"Куче", "тегло" :40 }{ "_id" :"cat", "name" :"Meow", "type" :"Cat", "weight" :7 }{ "_id" :"cat", "name" :"Scratch", "type" :"Cat ", "weight" :3 }{ "_id" :"dog", "name" :"Wag", "type" :"Dog", "weight" :20 }

Прожекции

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

Пример:

db.cats.aggregate( [
   { $project: { name: 1, _id: 0 } },
   { $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} }
] ) 

Резултат:

{ "name" :"Fluffy" }{ "name" :"Scratch" }{ "name" :"Meow" }{ "name" :"Wag" }{ "name" :"Bark" }{ " име" :"Пухкав" }

Премахване на дубликати

Можете да използвате $group етап за премахване на излишните дубликати от резултата.

Например, предишната заявка върна два домашни любимци, наречени Fluffy. Можем да добавим $group етап към тази заявка, за да елиминирате излишния дубликат, така че да бъде върнат само един Fluffy.

db.cats.aggregate( [
   { $project: { name: 1, _id: 0 } },
   { $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} },
   { $group: { _id: "$name" } }
] ) 

Резултат:

{ "_id" :"Мяу" }{ "_id" :"Ла" }{ "_id" :"Надраскване" }{ "_id" :"Размахване" }{ "_id" :"Пухкав" } 

Този път се връща само един Fluffy.

Несъответстващи колони

Едно от предимствата на $unionWith на MongoDB има над UNION ALL на SQL е, че може да се използва с несъответстващи колони.

SQL UNION клаузата изисква следното:

  • И двете заявки връщат един и същ брой колони
  • Колоните в същия ред
  • Съвпадащите колони трябва да са от съвместим тип данни

MongoDB $unionWith етап не налага тези ограничения.

Следователно бихме могли да използваме $unionWith да направите нещо подобно:

db.cats.aggregate( [
   { $set: { _id: "$_id" } },
   { $unionWith: { coll: "employees", pipeline: [ { $set: { _id: "$_id" } } ] } },
   { $sort: { type: 1, salary: -1 } }
] ) 

Резултат:

{ "_id" :2, "name" :"Сара", "заплата" :128000 }{ "_id" :5, "name" :"Бек", "заплата" :82000 }{ "_id" :4, "name" :"Chris", "salary" :45000 }{ "_id" :3, "name" :"Fritz", "salary" :25000 }{ "_id" :1, "name" :"Fluffy ", "type" :"Cat", "weight" :5 }{ "_id" :2, "name" :"Scratch", "type" :"Cat", "weight" :3 }{ "_id" :3, "име" :"Мяу", "тип" :"Котка", "тегло" :7 }

В този случай се присъединихме към cats колекция със employees колекция. employees колекцията нямаше същите полета като cats колекция, но това е добре – все още работи.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Надстройка до ClusterControl Enterprise Edition

  2. Как да свържете клиенти на mongodb към локален Meteor MongoDB

  3. Как да извлечете подробностите от mongo db и да изпратите или съхраните в обект в метода nodejs Fork

  4. Предотвратете дублиране на влизане с FOSUserBundle

  5. Как да наблюдавате MongoDB с Prometheus &ClusterControl