MongoDB Academy · Ders

İşlem Hattında $sort, $limit ve $skip

Öğrenenler, toplulaştırma sonuçlarını sıralayıp sayfalayacak ve $match ile $sort işlemlerini $group öncesine taşıyan iyileştirici kurallarını anlayacaklardır.

4. ders / 413 adım

İşlem Hattında $sort, $limit ve $skip, CoddyKit'te ücretsiz bir MongoDB Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, MongoDB Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. MongoDB Academy kursu toplamda 4 dersten oluşur.

Genel Bakış: Sonuçları Sıralama ve Sayfalara Bölme

Üç toplama işlem hattı aşaması sonuçların sırasını ve hacmini kontrol eder: $sort belgeleri bir veya daha fazla alana göre sıralar, $limit yalnızca ilk N belgeyi alır ve $skip ilk N belgeyi atar. Birlikte sıralama ve sayfalama işlemlerini gerçekleştirirler. Bunları işlem hattında nereye yerleştireceğinizi anlamanız performansı büyük ölçüde etkiler.

$sort Aşaması

$sort aşaması, belgeleri bir veya daha fazla alanın değerlerine göre sıralar. Artan sıralama için 1, azalan sıralama için -1 kullanın. Birden fazla alan belirtildiğinde belgeler önce ilk alana, eşitlik durumunda ikinci alana ve bu şekilde devam ederek sıralanır; bu, SQL'deki çok anahtarlı sıralama veya MongoDB'nin find().sort() yöntemiyle tamamen aynıdır.

// Sort by revenue descending, then alphabetically by name for ties
db.products.aggregate([
  { $group: { _id: '$category', revenue: { $sum: '$price' } } },
  { $sort: { revenue: -1, _id: 1 } }  // revenue desc, category name asc
]);

$sort ve İndeks Kullanımı

$sort ilk işlem hattı aşaması olduğunda (veya indeks kullanan bir $match aşamasını izlediğinde), MongoDB sıralamayı gerçekleştirmek için bir indeks kullanabilir; böylece bellekte sıralama yapma gereği tamamen ortadan kalkar. $sort, yeni alanlar üreten aşamalardan ($group veya $project gibi) sonra geldiğinde kullanılabilir bir indeks olmaz ve MongoDB bellekte sıralama gerçekleştirir. Büyük bellek içi sıralamalar (>100 MB) için allowDiskUse: true gerekir.

// Index-backed sort: $sort on indexed field before any transformation
db.orders.aggregate([
  { $match: { userId: 'u1' } },
  { $sort: { createdAt: -1 } }  // if createdAt is indexed, no in-memory sort
]);

// In-memory sort: $sort after $group (computed field, no index)
db.orders.aggregate([
  { $group: { _id: '$userId', total: { $sum: '$amount' } } },
  { $sort: { total: -1 } }  // in-memory: 'total' is a computed field
]);

$limit Aşaması

$limit yalnızca ilk N belgeyi sonraki aşamalara aktarır ve geri kalanları atar. Kullanımı basittir: geçişine izin verilecek en fazla belge sayısını belirten bir tam sayı aktarın. $lookup gibi maliyetli aşamalardan önce yerleştirilen $limit, gerçekleştirilen birleştirme veya arama işlemlerinin sayısını büyük ölçüde azaltır. Her zaman şu soruyu sorun: 'Erken sınırlama yapabilir miyim?'

// Top 10 best-selling products
db.orders.aggregate([
  { $group: { _id: '$productId', sold: { $sum: '$qty' } } },
  { $sort: { sold: -1 } },
  { $limit: 10 },  // only top 10 pass through
  // Only 10 lookups instead of thousands:
  { $lookup: { from: 'products', localField: '_id', foreignField: '_id', as: 'product' } }
]);

$skip Aşaması

$skip, akıştaki ilk N belgeyi atar. Toplamadaki karşılığı uzaklık tabanlı sayfalama işlemidir: sayfa başına 10 belge varsayılırsa 2. sayfa skip 10'dan başlar. Tutarlı sonuçlar üretmek için $skip her zaman $sort'tan sonra gelmelidir; sıralanmamış belgeleri atlamak öngörülemeyen sayfalar oluşturur. SQL OFFSET gibi, büyük uzaklıklarda $skip yavaştır; çünkü MongoDB atlanan tüm belgeleri yine de işlemek zorundadır.

const PAGE = 2;
const PAGE_SIZE = 10;

db.articles.aggregate([
  { $match: { status: 'published' } },
  { $sort: { publishedAt: -1 } },
  { $skip: (PAGE - 1) * PAGE_SIZE },  // skip page 1's 10 docs
  { $limit: PAGE_SIZE }               // take page 2's 10 docs
]);

İyileştirici: $sort + $limit Birleştirmesi

MongoDB'nin toplama iyileştiricisi, bir $sort aşamasının hemen ardından bir $limit aşaması geldiğini algıladığında bunları ilk N öğeyi seçen bir sıralamada birleştirir. MongoDB tüm belgeleri sıralayıp çoğunu atmak yerine, sıralama sırasında öncelik kuyruğunda yalnızca en iyi N adayı tutar. Böylece toplam veri miktarıyla orantılı bellek yerine O(N) bellek kullanılır. Bu iyileştirme otomatiktir; $sort aşamasını $limit aşamasının izlemesi yeterlidir.

// This pattern triggers the top-N sort optimisation
db.reviews.aggregate([
  { $match: { productId: 'p1' } },
  { $sort: { rating: -1, helpful: -1 } },  // sort
  { $limit: 5 }   // $sort + $limit merged into top-5 sort internally
]);
// MongoDB never sorts ALL reviews; it tracks only the best 5

İyileştirici: $match ve $sort Sıralamasını Değiştirme

Toplama iyileştiricisi, güvenli olduğu durumlarda bir $match aşamasını işlem hattında otomatik olarak daha erkene taşır. Örneğin, $sort'un hesaplamadığı bir alanda $sort, $match'ten önce geliyorsa iyileştirici, sıralanması gereken belge sayısını azaltmak için $match'i $sort'tan önceye taşır. İyileştiricideki değişiklikleri explain() çıktısında gözlemleyebilirsiniz.

// You write:
db.orders.aggregate([
  { $sort: { amount: -1 } },
  { $match: { status: 'completed' } }  // optimizer moves this BEFORE $sort
]);

// Optimized execution (equivalent to):
db.orders.aggregate([
  { $match: { status: 'completed' } },  // fewer docs to sort
  { $sort: { amount: -1 } }
]);

Dördünü Birleştirme: Eksiksiz Bir Liste Ucu

Ürünleri filtreler, sıralama ve sayfalama ile listeleyen gerçekçi bir API ucu, $match, $sort, $skip ve $limit aşamalarını doğru sırayla birleştirir. Desen her zaman şöyledir: filtrele → sırala → atla → sınırla. Bu sıra, MongoDB'nin gereksiz belgeleri atmadan önce hem filtreleme hem de (mümkün olduğunda) sıralama için indeksleri kullanmasını sağlar.

async function getProducts({ category, sort = 'price', page = 1, pageSize = 20 }) {
  return db.products.aggregate([
    { $match: { category, inStock: true } },   // 1. filter
    { $sort: { [sort]: 1 } },                  // 2. sort
    { $skip: (page - 1) * pageSize },          // 3. offset
    { $limit: pageSize }                       // 4. take page
  ]).toArray();
}

Derin Uzaklıklarda $skip Performansı

$skip ile ilgili temel sorun, MongoDB'nin atlanan her belgeyi yine de işleyip atmak zorunda olmasıdır. Sayfa başına 20 öğe olduğunda 1000. sayfada MongoDB, 20 belgeyi döndürmeden önce 19.980 belgeyi atar. Sayfalar derinleştikçe işlem giderek yavaşlar. Kullanıcıların genellikle 5-10. sayfaların ötesine geçmediği herkese açık arama veya akış API'lerinde uzaklık tabanlı sayfalama uygundur. Sık kullanılan derin sayfalama işlemleri için anahtar kümesi sayfalaması gerekir.

// Page 1000 is SLOW: MongoDB processes and discards 19,980 docs
db.posts.aggregate([
  { $sort: { createdAt: -1 } },
  { $skip: 19980 },  // 999 * 20
  { $limit: 20 }
]);

// Keyset pagination: always fast regardless of page depth
db.posts.aggregate([
  { $match: { createdAt: { $lt: lastSeenTimestamp } } },  // cursor
  { $sort: { createdAt: -1 } },
  { $limit: 20 }
]);

$sort Bellek Sınırı ve allowDiskUse

Toplama işlem hattındaki bellek içi $sort, varsayılan olarak 100 MB ile sınırlıdır. Sıralama bu sınırı aşarsa işlem hattı QueryExceededMemoryLimitNoDiskUseAllowed hatasıyla başarısız olur. Diske taşmayı etkinleştirmek için aggregate() yöntemine ikinci bağımsız değişken olarak { allowDiskUse: true } aktarın. Alternatif olarak erken bir $match uygulayın veya sıralama girdisinin boyutunu azaltmak için destekleyici bir indeks kullanın.

// Enable disk use for large sorts
db.events.aggregate(
  [
    { $match: { year: 2024 } },
    { $sort: { timestamp: -1 } },
    { $group: { _id: '$userId', events: { $push: '$type' } } }
  ],
  { allowDiskUse: true }  // allows spilling to disk
);

Sonuçlarla Birlikte Toplam Sayıyı Alma

Yaygın bir API deseni, sayfalara bölünmüş sonuçlarla toplam sayıyı tek bir veritabanı gidiş-dönüşünde döndürmektir. İşlem hattını iki paralel dala ayırmak için $facet kullanın: biri $skip/$limit sonuçları, diğeri $count için. Bu yaklaşım, iki ayrı toplama çağrısını önler ve tüm belgeleri ayrı olarak saymaktan daha verimlidir.

db.products.aggregate([
  { $match: { category: 'electronics' } },
  { $sort: { price: 1 } },
  { $facet: {
    // Branch 1: paginated results
    data: [
      { $skip: 0 },
      { $limit: 20 }
    ],
    // Branch 2: total count
    total: [
      { $count: 'count' }
    ]
  }}
]);
// Output: { data: [...20 docs...], total: [{ count: 348 }] }

Kısa Kontrol

Toplama işlem hattındaki $sort, $limit ve $skip aşamalarını anlayıp anlamadığınızı test edin.

Ders Özeti

Bu derste şunları öğrendiniz: $sort belgeleri sıralar ve erken yerleştirildiğinde indeks kullanımından yararlanır; $limit ilk N belgeyi alır ve $sort ile birleşerek verimli bir ilk N sıralaması oluşturur; $skip uzaklık tabanlı sayfalamayı gerçekleştirir, ancak derin uzaklıklarda performansı düşer. Sırada, koleksiyonları birleştirmek için $lookup da dahil olmak üzere gelişmiş toplama aşamalarını inceleyeceğiz.

Başlamak ücretsiz

Yapay zeka eğitmeniyle JavaScript öğren — ücretsiz

Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.

Kurslar
30
Dersler
120

Sıkça Sorulan Sorular

“İşlem Hattında $sort, $limit ve $skip” dersi ücretsiz mi?

Evet — “İşlem Hattında $sort, $limit ve $skip” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve MongoDB Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. MongoDB Academy kursu toplamda 4 dersten oluşur.

“İşlem Hattında $sort, $limit ve $skip” dersinde ne öğreneceğim?

Öğrenenler, toplulaştırma sonuçlarını sıralayıp sayfalayacak ve $match ile $sort işlemlerini $group öncesine taşıyan iyileştirici kurallarını anlayacaklardır. MongoDB Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

MongoDB Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te MongoDB Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.

“İşlem Hattında $sort, $limit ve $skip” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu MongoDB Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her MongoDB Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. İşlem Hattı Kavramları: Aşamalar, İşleçler ve İfadeler
  2. $match ve $project: Filtreleme ve Yeniden Şekillendirme
  3. $group: Toplama ve Toplamları Hesaplama
  4. İşlem Hattında $sort, $limit ve $skip
← MongoDB Academy Sayfasına Dön