MongoDB etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
MongoDB etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

24 Şubat 2021 Çarşamba

MongoDB bulkWrite

Giriş
Açıklaması şöyle
Use bulk write to write multiple database changes with a single batch query
Örnek
Şöyle yaparız
//Don'ts
db.collection.updateOne({itemId: 1}, { $set: { "stock" : 3} })
db.collection.updateOne({itemId: 2}, { $set: { "stock" : 1} })
db.collection.updateOne({itemId: 3}, { $set: { "stock" : 4} })
//Do's
db.collection.bulkWrite(
   [
     { updateOne :
       {
         "filter": {itemId: 1},
         "update": {$set: {"stock" : 3}
       }
     },
     { updateOne :
       {
         "filter": {itemId: 2},
         "update": {$set: {"stock" : 1}
       }
     },
     { updateOne :
       {
         "filter": {itemId: 3},
         "update": {$set: {"stock" : 4}
       }
     }      
   ]
);

22 Şubat 2021 Pazartesi

MongoDB aggregate ve avg

Örnek
Şöyle yaparız
> db.car.aggregate([
... { $group: { _id: "$make", avg_price: { $avg: "$price" }}}
... ])
{ "_id" : "hyundai", "avg_price" : 36333.333333333336 }
{ "_id" : "BMW", "avg_price" : 47400 }
{ "_id" : "ford", "avg_price" : 35333.333333333336 }
SQL olarak şöyledir
mysql> select make, avg(price)
    -> from car
    -> group by make;
+---------+------------+
| make    | avg(price) |
+---------+------------+
| BMW     | 47400.0000 |
| ford    | 35333.3333 |
| hyundai | 36333.3333 |
+---------+------------+
Örnek
Şöyle yaparız. Yukarıdaki örnek ile aynı. Sadece 2019 modeller seçiliyor.
> db.car.aggregate([
... { $match: { year: "2019" }}, ... { $group: { _id: "$make", avg_price: { $avg: "$price" }}} ... ]) { "_id" : "BMW", "avg_price" : 53000 } { "_id" : "ford", "avg_price" : 42000 } { "_id" : "hyundai", "avg_price" : 41000 }
SQL olarak şöyledir
mysql> select make, avg(price)
    -> from car
    -> where year = "2019"
    -> group by make;
+---------+------------+
| make    | avg(price) |
+---------+------------+
| BMW     | 53000.0000 |
| ford    | 42000.0000 |
| hyundai | 41000.0000 |
+---------+------------+

MongoDB update metodu

Örnek
Şöyle yaparız
> db.car.update(
... { make: "bmw" },
... { $set: { make: "BMW" }},
... { multi: true }
... )
WriteResult({ "nMatched" : 5, "nUpserted" : 0, "nModified" : 5 })
SQL olarak şöyledir
mysql> update car
    -> set make = "BMW"
    -> where make = "bmw";
Query OK, 5 rows affected (0.05 sec)
Rows matched: 5  Changed: 5  Warnings

8 Şubat 2021 Pazartesi

MongoDB sort metodu

Giriş
1 ise artan -1 ise azalan olarak sıralar
Örnek
Şöyle yaparız
db.collection.find().sort(key:1|-1) //syntax

db.student.find().sort({"_id":-1})
//To display all students in ascending order

MongoDB unset

Giriş
$updateOne + $unset kullanılırsa, dokümandan bir alan siler. Açıklaması şöyle
$unset:- In MongoDB, the $unset operator is used to delete a particular field. The value specified in the $unset expression does not make any impact on the operation. The $unset has no effect when the field does not exist in the document.
Örnek
Şöyle yaparız
db.collection.updateOne(filter,{ $unset: { <field1>: "", ... } }) //syntax
Bu işlemin tam tersi $set. Şöyle yaparız
db.student.updateOne({"_id":4},{$set:{"zipcode":"54682"}})
Eğer değiştirmeye çalıştığımız şey array ise $push ve $pull kullanılır. Eklemek için şöyle yaparız
db.collection.updateOne(filter,{ $push: { <field1>: <value1>, ... } }) //syntax

db.student.updateOne({_id:4},{$push:{"subject":"Urdu"}})
Silmek için şöyle yaparız
db.collection.updateOne(filter,{ $pull: { <field1>: <value1>, ... } }) //syntax

db.student.updateOne({_id:4},{$pull:{"subject":"Urdu"}})





MongoDB aggregate ve project - Projection Yapmak

Giriş
Açıklaması şöyle
Naturally, we’re going to want to reduce the documents into smaller objects — returning just the fields we want, or aliasing their names. In the SQL paradigm, this sounds like a SELECT , for Mongo it’s $project .

The structure you pass to $project is a field mapping:
<field>: <1 or true>
_id: <0 or false>
<field>: <expression>
<field>: <0 or false>
Örnek
Şöyle yaparız. Burada sadece id ve bookName alanları gösterilir.
db.books.find({}, {"bookName": 1}).pretty()
Eğer id alanını da saklamak istersek şöyle yaparız. Burada sadece bookName alanı gösterilir.
db.books.find({}, {"_id": 0, "bookName": 1}).pretty()
Örnek
Şöyle yaparız. Burada her subject'in bir book dizisi var. Book dizisi dolaşılıyor ve project ediliyor. Daha sonra projection sort ediliyor.
db.Subject.aggregate([ 
  {
    $project:{
  "subject.subCode":1,
      "subject.book.bookTitle":1,
      "subject.book.publisher":1
  },
  {
    $unwind:"$subject.book"
  },
  {
    $sort:{
      "subject.subCode":1,
      "subject.book.publisher":-1
    }  
  }
]).pretty()

MongoDB aggregate ve skip

Örnek
Sonucu iki taneye indirgeyip, sondakine erişmek için şöyle yaparız
db.articles.aggregate([
  { $match: { score: { $gt: 60 }}},
  { $limit: 2},
  { $skip: 1 }
])

MongoDB aggregate ve match

Giriş
Match ile nesneler belirtilen kritere göre seçilirler. Yani "where" anlamına gelir. Match kullanırken and/or gibi şeyler kullanılabilir. Ayrıca eşleştirmek için sadece eşitlik değil, gt gibi büyüklük/küçüklük karşılaştırması da yapılabilir

Örnek - match + group + sum
Designing Data Intensive Applications kitabında gösterildiği gibi şöyle yaparız. Burada gruplama yapılıyor ve gruptaki toplam bulunuyor.
db.observations.aggregate([
  { $match: { family: "Sharks" } },
  { $group: {
      _id: {
        year: { $year: "$observationTimestamp" },
        month: { $month: "$observationTimestamp" }
      },
      totalAnimals: { $sum: "$numAnimals" }
    } }
]);
Eğer SQL kullanıyor olsaydık aynı şey şöyle yapardık
SELECT date_trunc('month', observation_timestamp) AS observation_month,
  SUM(num_animals) AS total_animals
FROM observations
WHERE family = 'Sharks'
GROUP BY observation_month;
Örnek - or 
Şöyle yaparız. Bu örnek diğerlerine benziyor. Farklı olarak sadece match için $or kullanılıyor.
db.collection.aggregate([
  {
    $match: {
      $or: [
        {
          "subject.type": "Core"
        },
        {
          "subject.type": "Elective"
        }
      ]
    }
  },
  {
    $group: {
      _id: "$subject.type",
      count: {
        $sum: 1
      }
    }
  }
])
Örnek - $or + $gt
Şöyle yaparız
db.articles.aggregate(
    [{ $match: { 
          $or: [{ 
            score: { $gt: 90 } 
          }, { 
            author: "dave" 
          }}] 
    }}]
);

4 Şubat 2021 Perşembe

MongoDB aggregate ve lookup metodu - join İçindir

Giriş
lookup için açıklama şöyle. Sadece unsharded durumda çalışıyor.
Performs a left outer join to an unsharded collection in the same database to filter in documents from the “joined” collection for processing.
Bir başka açıklama şöyle. Sürüm 3.2 ile geliyor.
Until version 3.2 of MongoDB doing joins wasn’t possible, but with that version came the $lookup aggregation stage operator. The introduction of $lookup allows for left outer joins to be performed on collections in the same database which are not sharded.
lookup() eklenmeden önce denormalization tavsiye ediliyordu. Açıklaması şöyle. Eğer Elimizde bir Story nesnesi varsa, bunu kullanan "User Id" ve "User Name" alanları da Story içinde saklanıyordu. Burada User Name saklandığı için İlişkisel veri tabanı kullanmaya alışık kişiler denormalization ihlali olduğunu düşündükleri için itiraz ediyorlardı
Caching to Avoid N+1
When we display our list of stories, we'll need to show the name of the user who posted the story. If we were using a relational database, we could perform a join on users and stores, and get all our objects in a single query. But MongoDB does not support joins and so, at times, requires bit of denormalization. Here, this means caching the 'username' attribute.

A Note on Denormalization

Relational purists may be feeling uneasy already, as if we were violating some universal law. But let’s bear in mind that MongoDB collections are not equivalent to relational tables; each serves a unique design objective. A normalized table provides an atomic, isolated chunk of data. A document, however, more closely represents an object as a whole. In the case of a social news site, it can be argued that a username is intrinsic to the story being posted.
Söz Dizimi
Söz dizimi şöyledir
- from ile karşı collection belirtilir. 
- localField ile kendi collection nesnemdeki alan belirtilir. 
- foreignField ile karşı collection'daki alan belirtilir.
{ $lookup: {
  from: <collection to join>,
  localField: <field from the input documents>,
  foreignField: <field from the documents of the "from" collection>,
  as: <output array field>
} }
Örnek
Elimizde iki tane collection (Orders ve Inventory) olsun. Order nesnesiyle Inventory nesnesini birleştirmek için şöyle yaparız
// A collection Orders contains the following documents:
{ "_id" : 1, "item" : "abc", "price" : 12, "quantity" : 2 }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1 }
{ "_id" : 3  }

// Another collection Inventory contains the following documents:
{ "_id" : 1, "sku" : "abc", description: "product 1", "instock" : 120 }
{ "_id" : 2, "sku" : "def", description: "product 2", "instock" : 80 }
{ "_id" : 3, "sku" : "ijk", description: "product 3", "instock" : 60 }
{ "_id" : 4, "sku" : "jkl", description: "product 4", "instock" : 70 }
{ "_id" : 5, "sku": null, description: "Incomplete" }
{ "_id" : 6 }

// The following aggregation operation on the orders collection joins the documents from
// orders with the documents from the inventory collection using the fields item from the
// orders collection and the sku field from the inventory collection:
db.orders.aggregate([
    {
      $lookup:
        {
          from: "inventory",
          localField: "item",
          foreignField: "sku",
          as: "inventory_docs"
        }
   }
])
Çıktı olarak şunu alırız
// Returns these documents
{
  "_id" : 1,
   "item" : "abc",
  "price" : 12,
  "quantity" : 2,
  "inventory_docs" : [
    { "_id" : 1, "sku" : "abc", description: "product 1", "instock" : 120 }
  ]
}
{
  "_id" : 2,
  "item" : "jkl",
  "price" : 20,
  "quantity" : 1,
  "inventory_docs" : [
    { "_id" : 4, "sku" : "jkl", "description" : "product 4", "instock" : 70 }
  ]
}
{
  "_id" : 3,
  "inventory_docs" : [
    { "_id" : 5, "sku" : null, "description" : "Incomplete" },
    { "_id" : 6 }
  ]
}
Örnek
Elimizde bir Product olsun. Her Product'in içinde items dizisi var.
[
  {
   "_id": "789",
   "product_name": "test product1",
   "items":[
      {
         "price": 55,
         "image": "default.png",
         "category":[
             "123",
          ],
      }
    ]
  }
...
]
Elimizde bir ProductCategory olsun
[
  {
   "_id": "123",
   "name": "sample category 1"
  },
  {
   "_id": "456",
   "name": "sample category 2"
  },
]
Her Product'ın içindeki item nesnesinin ait olduğu category'i istelim. Şöyle yaparız. Burada unwind items ile bu dizi dolaşılır, lookup ile item'a ait category çekilir.
Product.aggregate([
  { "$unwind": "$items" },
  { "$lookup": {
    "from": "product_category",
    "localField": "items.category",
    "foreignField": "_id",
    "as": "items.category"
  }},
  { "$group": {
    "_id": "$_id",
    "items": { "$push": "$items" }
  }}
])
Çıktı olarak şunu alırız
[
  {
   "_id": "789",
   "product_name": "test product1",
   "items":[
      {
         "price": 55,
         "image": "default.png",
         "category":[
            {
              "_id": "123",
              "name": "sample category 1"
            } 
          ]
      }
    ]
  }
...
]
Örnek
Elimizde şöyle bir veri olsun. Burada Tag yani etiketler var. Her tag'in ismi ve size alanı var. tag1 isimli etiketin size alanı m, s gibi değerlere olabiliyor. Yani birden fazla tag1 etiketi var.
// collections
db={
  Tag: [
    {
      "_id": 1,
      "name": "task",
      "size": "m",
      "tag": "tag1"
    },
    {
      "_id": 2,
      "name": "task",
      "size": "m",
      "tag": "tag1"
    },
    {
      "_id": 3,
      "name": "task",
      "size": "s",
      "tag": "tag1"
    },
    {
      "_id": 4,
      "name": "task",
      "size": "s",
      "tag": "tag2"
    },
    {
      "_id": 5,
      "name": "task",
      "size": "xl",
      "tag": "tag1"
    }
  ],
  UserTag: [
    {
      user: 1,
      tag: "tag1"
    },
    {
      user: 2,
      // pipeline doesn't care if a user has multiple tags
      tag: [
        "tag2",
        "tag1"
      ]
    }
  ]
}
2 numaralı kullanıcının etiketlerini çekmek için şöyle yaparız. Burada ilk $group işlemiyle her bir tag + size için gruplama yapılıyor ve count ile kaç tane oldukları sayılıyor. Daha sonra ikinci gruplamayla ilk gruplamanın çıktısı sadece tag alanına göre gruplanıyor ve size + count değerleri dizi şeklinde toplanıyor
db.UserTag.aggregate([
  { // match user
    $match: {
      user: 2
    }
  },
  { // lookup each of the users tags from the tag collection
    $lookup: {
      from: "Tag",
      localField: "tag",
      foreignField: "tag",
      as: "tags"
    }
  },
  {
    $unwind: "$tags"
  },
  { // group by the tag and size, sum results
    $group: {
      _id: {
        tag: "$tags.tag",
        size: "$tags.size"
      },
      count: {
        $sum: 1
      }
    }
  },
  {
    $group: {
      // group just by tag, send sizes into an array with their counts
      // can hardcode this to just extract the 4 types of course
      _id: "$_id.tag",
      sizes: {
        $push: {
          size: "$_id.size",
          count: "$count"
        }
      }
    }
  }
])
Çıktı olarak şunu alırız. Her bir tag ismi ayrı ayrı neslerdir. Bu tag'lerin size değerine göre kaç tane oldukları da sizes dizisinde görülebilir.
// output
[
  {
    "_id": "tag2",
    "sizes": [
      {
        "count": 1,
        "size": "s"
      }
    ]
  },
  {
    "_id": "tag1",
    "sizes": [
      {
        "count": 1,
        "size": "s"
      },
      {
        "count": 1,
        "size": "xl"
      },
      {
        "count": 2,
        "size": "m"
      }
    ]
  }
]