---
title: 'Bağlam Sorguları'
source: 'https://academia.sh/tr/kurslar/arama-motorlari/baglam-sorgulari'
course: 'Arama Motorları ve Metin Erişimi'
language: tr
updated: '2026-08-17T18:09:01+00:00'
license: 'CC BY-SA 4.0'
---

# Bağlam Sorguları

Zorunlu, olumsuz ve isteğe bağlı koşullar aynı bileşik sorguda ölçülür: olumsuz koşul kümeden 512 belge çıkarır, isteğe bağlı koşul bir belge bile çıkarmadan ilk on sonucun dokuzunu değiştirir, ama zorunlu koşul yokken aynı isteğe bağlı koşul kümeyi belirleyen koşula dönüşür.

Önceki iki derste kurulan koşulların hepsi aynı türdendi: koşulu sağlamayan belge
kümeden düşerdi. Katalog soruları bu kadar tek biçimli değildir. Bir okur şunu söyler:
"Çocuk kitabı olsun, almanca olmasın, resimli olanlar üstte olsun." Üç istek de tek bir
cümlede geçer, ama üçü aynı işi yapmaz. Birincisi kümeyi belirler, ikincisi kümeden
çıkarır, üçüncüsü kümeden hiç kimseyi çıkarmaz — yalnız listenin başını değiştirir.

Bileşik sorgu bu ayrımı **koşul bağlamı** ile yapar. **Zorunlu koşul** (must)
sağlanmayan belgeyi eler. **Olumsuz koşul** (must not) sağlayan belgeyi eler. **İsteğe
bağlı koşul** (should) hiçbir belgeyi elemez; sağlayan belgeye puan ekler. Bu ders üç
bağlamın kümeye ve sıraya etkisini ayrı ayrı sayar ve isteğe bağlı koşulun bir yerde
kural değiştirdiğini gösterir.

## Derlem ve Puan Kuralı

Derlem önceki derslerin modülüdür: 6.000 kitap kaydı, tohum 271828, belirlenimli üretim.
**SI6 (varsayım):** bu derste puan, karşılanan isteğe bağlı koşul sayısıdır; eşitlik
belge numarasıyla bozulur. Terim sıklığına ve seyrekliğe dayanan gerçek puan modeli bu
konunun beşinci dersinde kurulur — burada ölçülen şey puanın büyüklüğü değil, isteğe
bağlı koşulun sıraya dokunup kümeye dokunmaması.

```js
// derlem.mjs — kutuphane katalogu derlemi ve konum bilgili ters dizin.
// Tohum 271828, 6000 belge; konudaki butun olcumler bu modulu paylasir.
export const TOHUM = 271828, N = 6000;
let c = TOHUM;                                       // gorunur tohum, belirlenimli uretec
const r = () => { c = (c + 0x6d2b79f5) | 0; let t = Math.imul(c ^ (c >>> 15), 1 | c);
  t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; };
const sec = (d, e = 1) => d[Math.floor(r() ** e * d.length)];   // e>1: bas ogeler sik, son ogeler seyrek

const SIFAT = ["eleştirel", "kısa", "resimli", "seçme", "karşılaştırmalı"];
const TUR = ["deneme", "öykü", "roman", "inceleme", "antoloji"];
const ALAN = ["çocuk", "tarih", "bilim", "felsefe", "toplum"];
const SON = ["seçkisi", "kitabı", "derlemesi", "dizisi"];
const NIT = ["kapsamlı", "özlü", "tanıtıcı", "tartışmalı"];
const KONU = ["eğitim", "göç", "kent", "bellek", "doğa", "müzik", "hukuk", "kimlik", "emek", "aile",
  "savaş", "gelenek", "sağlık", "yolculuk", "mimarlık", "arkeoloji", "denizcilik", "gökbilim"];
const YAZAR = ["Ahmet Yıldız", "Zeynep Kaya", "Kemal Demir", "Elif Şahin", "Necati Aydın"];
const DIL = ["türkçe", "ingilizce", "almanca"];

export const KATALOG = [];
for (let i = 1; i <= N; i += 1) {
  const s = sec(SIFAT, 1.5), t = sec(TUR, 1.5), a = sec(ALAN, 2), k = r();
  const desen = k < 0.18 ? `${s} ${t}` : k < 0.30 ? `${s} bir ${t}`
    : k < 0.40 ? `${s} ve kuramsal ${t}` : k < 0.50 ? `${t} ve ${s} inceleme`
    : k < 0.70 ? `${s} bir anlatı` : k < 0.88 ? `çağdaş bir ${t}` : "alan yazını taraması";
  KATALOG.push({ id: `K-${String(i).padStart(4, "0")}`, ad: `${a} ${t} ${sec(SON)}`,
    ozet: `${a} alanında ${desen}; ${sec(KONU, 3)} ve ${sec(KONU, 3)} üzerine ` +
      `${sec(NIT)} bir ${sec(TUR, 1.5)} olarak okunabilir.`,
    etiket: [a, t], yazar: sec(YAZAR), yil: 1990 + Math.floor(r() * 35), dil: sec(DIL, 2) });
}

export const belirtecle = (m) => m.toLocaleLowerCase("tr").split(/[^\p{L}\p{N}]+/u).filter(Boolean);

// Ters dizin: "alan|terim" -> Map(belge sirasi -> konumlar); uzunluk: alan basina belirtec sayisi.
export function tersDizin(alanlar) {
  const g = new Map(), uzunluk = new Map();
  KATALOG.forEach((b, i) => {
    for (const alan of alanlar) {
      const tk = belirtecle(String(b[alan]));
      uzunluk.set(`${alan}|${i}`, tk.length);
      tk.forEach((t, p) => {
        let l = g.get(`${alan}|${t}`); if (!l) g.set(`${alan}|${t}`, (l = new Map()));
        let k2 = l.get(i); if (!k2) l.set(i, (k2 = [])); k2.push(p);
      });
    }
  });
  return { g, uzunluk };
}
```

## Üç Bağlamın Ölçümü

```js
// baglam.mjs — zorunlu, olumsuz ve istege bagli kosullar. Ayni dizinde derlem.mjs bulunur.
// Istege bagli kosul kumeden belge elemez; yalniz puan uretir. Puan burada karsilanan
// istege bagli kosul sayisidir; esitlik belge numarasiyla bozulur.
import { KATALOG, TOHUM, tersDizin } from "./derlem.mjs";
const { g } = tersDizin(["ad", "ozet", "etiket", "dil"]);
const kume = (alan, terim) => new Set(g.get(`${alan}|${terim}`)?.keys() ?? []);

function calistir(sorgu, s) {
  let aday = null;
  for (const [alan, terim] of sorgu.zorunlu ?? []) {
    const k = kume(alan, terim); s.taranan += k.size;
    aday = aday === null ? [...k] : aday.filter((d) => k.has(d));
  }
  const istek = (sorgu.istege ?? []).map(([a, t]) => { const k = kume(a, t); s.taranan += k.size; return k; });
  if (aday === null) {                       // zorunlu kosul yoksa kumeyi istege bagli kosullar belirler
    const b = new Set();
    for (const k of istek) for (const d of k) b.add(d);
    aday = [...b];
  }
  for (const [alan, terim] of sorgu.olumsuz ?? []) {
    const k = kume(alan, terim); s.taranan += k.size;
    aday = aday.filter((d) => !k.has(d));
  }
  aday.sort((x, y) => x - y);
  const puan = new Map(aday.map((d) => [d, istek.filter((k) => k.has(d)).length]));
  const sirali = [...aday].sort((x, y) => puan.get(y) - puan.get(x) || x - y);
  return { kume: aday, puan, sirali };
}
const olc = (ad, sorgu) => {
  const s = { taranan: 0 }, c = calistir(sorgu, s);
  console.log(`${ad.padEnd(38)} ${String(c.kume.length).padStart(4)} belge   taranan giris ${String(s.taranan).padStart(5)}`);
  return c;
};

console.log(`derlem ${KATALOG.length} belge, tohum ${TOHUM}`);
const Z = [["etiket", "çocuk"]], I = [["ozet", "resimli"], ["ad", "öykü"]], O = [["dil", "almanca"]];
const a = olc("zorunlu[etiket:çocuk]", { zorunlu: Z });
const b = olc("zorunlu + olumsuz[dil:almanca]", { zorunlu: Z, olumsuz: O });
const c = olc("zorunlu + istege bagli[resimli, öykü]", { zorunlu: Z, istege: I });
const d = olc("zorunlu + istege bagli + olumsuz", { zorunlu: Z, istege: I, olumsuz: O });
const e = olc("yalniz istege bagli[resimli, öykü]", { istege: I });
console.log(`olumsuz kosulun cikardigi belge ${a.kume.length - b.kume.length}`);
console.log(`istege bagli kosulun kumeye etkisi ${c.kume.length - a.kume.length} belge`);

const ilkOn = (l) => l.slice(0, 10).map((x) => KATALOG[x].id);
const degisen = ilkOn(c.sirali).filter((x) => !ilkOn(a.sirali).includes(x)).length;
console.log(`ilk on: zorunlu ${ilkOn(a.sirali).join(" ")}`);
console.log(`ilk on: +istege ${ilkOn(c.sirali).join(" ")}   degisen ${degisen}/10`);
const ikiPuan = c.sirali.filter((x) => c.puan.get(x) === 2);
console.log(`iki istege bagli kosulu da karsilayan ${ikiPuan.length} belge; ` +
  `ilki ${KATALOG[ikiPuan[0]].id} zorunlu sirada ${a.kume.indexOf(ikiPuan[0]) + 1}. basamaktaydi`);
const oynama = ikiPuan.map((x) => a.kume.indexOf(x) + 1 - (c.sirali.indexOf(x) + 1));
console.log(`bu belgelerin basamak kazanci ortalama ${Math.round(oynama.reduce((x, y) => x + y, 0) / oynama.length)}, ` +
  `en buyugu ${Math.max(...oynama)}`);
```

```
derlem 6000 belge, tohum 271828
zorunlu[etiket:çocuk]                  2678 belge   taranan giris  2678
zorunlu + olumsuz[dil:almanca]         2166 belge   taranan giris  3800
zorunlu + istege bagli[resimli, öykü]  2678 belge   taranan giris  4638
zorunlu + istege bagli + olumsuz       2166 belge   taranan giris  5760
yalniz istege bagli[resimli, öykü]     1802 belge   taranan giris  1960
olumsuz kosulun cikardigi belge 512
istege bagli kosulun kumeye etkisi 0 belge
ilk on: zorunlu K-0004 K-0008 K-0016 K-0018 K-0020 K-0023 K-0024 K-0026 K-0033 K-0037
ilk on: +istege K-0037 K-0072 K-0078 K-0080 K-0216 K-0345 K-0371 K-0518 K-0615 K-0712   degisen 9/10
iki istege bagli kosulu da karsilayan 82 belge; ilki K-0037 zorunlu sirada 10. basamaktaydi
bu belgelerin basamak kazanci ortalama 1263, en buyugu 2574
```

## Küme: İki Koşul Türü Eler, Biri Elemez

Zorunlu koşul tek başına 2.678 belge döndürür — çocuk etiketli kitaplar. Olumsuz koşul
eklendiğinde küme 2.166'ya iner: 512 belge çıkar, hepsi almanca kayıtlardır. Olumsuz
koşulun ürettiği sayı hep bir çıkarmadır; kümeye asla belge eklemez ve tek başına
kullanıldığında anlamı belirsizdir, çünkü "almanca olmayan" ifadesi hangi kümeden
çıkarılacağını söylemez.

Üçüncü satır dersin çekirdeğidir. Aynı zorunlu koşula iki isteğe bağlı koşul eklendi ve
küme **2.678 belge olarak kaldı**: giren yok, çıkan yok, fark sıfır. Resimli olmayan ve
adında "öykü" geçmeyen bir kitap sonuç listesinden düşmedi; yalnız puanı sıfır kaldı.
Dördüncü satır aynı sorguya olumsuz koşulu geri koyar ve küme yine 2.166'ya iner — çünkü
kümeyi değiştiren şey isteğe bağlı koşul değil, olumsuz koşuldur.

Beşinci satır kuralın sınırını gösterir ve pratikte en çok yanlış anlaşılan noktadır.
Zorunlu koşul kaldırıldığında, aynı iki isteğe bağlı koşul kümeyi 1.802 belgeye indirir.
İsteğe bağlı koşul burada birden elemeye başlamış değildir; olan şey şudur: kümeyi
belirleyen hiçbir koşul kalmayınca **en az bir isteğe bağlı koşulun sağlanması** gerekir,
yoksa sorgu bütün derlemi döndürürdü. Yani "isteğe bağlı koşul kümeyi değiştirmez" cümlesi
koşulsuz doğru değildir; doğrusu şudur: **kümeyi belirleyen başka bir koşul varsa** isteğe
bağlı koşul kümeye dokunmaz. Bir arayüzde ağırlıklandırma amacıyla eklenen bir koşulun,
zorunlu koşulun kaldırıldığı bir durumda sonucu 6.000'den 1.802'ye düşürmesi bu kuraldan
gelir.

## Sıra ve Bedel: Elemeyen Koşulun Ödettiği

Küme değişmediği hâlde liste tanınmaz hâle gelir. Zorunlu koşulun tek başına verdiği ilk
on sonuç K-0004 ile başlar; isteğe bağlı koşullar eklendiğinde ilk onun **dokuzu**
değişir. Ayakta kalan tek kayıt K-0037'dir ve o da onuncu basamaktan birinci basamağa
çıkmıştır. İki isteğe bağlı koşulu birden karşılayan 82 belge vardır; bu belgeler
ortalama 1.263 basamak yukarı çıkar, en çok yükselen 2.574 basamak kazanır. 2.678
belgelik bir listede 2.574 basamaklık bir sıçrama, belgenin listenin sonundan başına
gelmesi demektir.

Bedel tarafı da elemeyen koşulun bedava olmadığını gösterir. Zorunlu koşul tek başına
2.678 giriş okur. İsteğe bağlı iki koşul eklendiğinde okuma 4.638 girişe çıkar: %73,2
artış, tek bir belge bile elenmeden. Bunun nedeni açıktır — isteğe bağlı koşulun puana
katkısını hesaplamak için gönderi listesinin tamamı okunmalıdır, oysa zorunlu koşul aday
kümesi küçüldükçe daha az iş yapar. Üç bağlamın hepsi bir aradayken okuma 5.760 girişe
ulaşır; bunun 1.122'si yalnız 512 belgeyi çıkarmak için okunan olumsuz koşul listesidir.

Buradan çıkan işletim kuralı şudur: bir koşulun ucuz olup olmadığı, kaç belge elediğine
değil, kaç giriş okuttuğuna bakarak söylenir. Kümeyi hiç değiştirmeyen bir koşul en
pahalı koşul olabilir.

## Özet

- Zorunlu koşul kümeyi belirler, olumsuz koşul kümeden çıkarır, isteğe bağlı koşul
  yalnız puan üretir; 6.000 belgelik derlemde (tohum 271828) olumsuz koşul 512 belge
  çıkarır, isteğe bağlı koşul 0 belge çıkarır.
- İsteğe bağlı koşulun kümeye etkisizliği koşulludur: kümeyi belirleyen başka bir koşul
  yoksa en az biri sağlanmalıdır ve küme 6.000 yerine 1.802 belge olur.
- Küme sabitken sıra baştan yazılır: ilk on sonucun dokuzu değişir, iki isteğe bağlı
  koşulu karşılayan 82 belge ortalama 1.263 basamak yükselir, en çok yükselen 2.574
  basamak kazanır.
- Elemeyen koşul bedavaya çalışmaz: isteğe bağlı iki koşul taranan girişi 2.678'den
  4.638'e çıkarır, hiçbir belgeyi elemeden.
- Bir koşulun bedeli elediği belge sayısıyla değil, okuttuğu gönderi girişiyle ölçülür.

## Sonraki Adım

Üç bağlam da bir noktada birleşiyor: hepsi puanlayıcının önünden geçiyor. Zorunlu koşul
kümeyi belirlerken aynı zamanda puana katkı veriyor, isteğe bağlı koşul zaten yalnız
bunun için var. Oysa katalog koşullarının bir bölümü puana hiç katılmamalıdır. "Yayın
yılı 2010 ve sonrası" ya da "dili türkçe" gibi bir koşul ya sağlanır ya sağlanmaz; bir
kitabın 2015 basımı olması onu 2011 basımı bir kitaptan daha ilgili yapmaz. Bu koşullar
ayrı bir bağlamda değerlendirilir ve o bağlamın iki sonucu vardır: puan hesabı
kısalır ve sonuç yeniden kullanılabilir hâle gelir, çünkü aynı koşul her sorguda aynı
belgeleri verir. Sonraki ders aynı koşulu iki bağlamda çalıştırır, kümenin aynı kalıp
sıranın değiştiğini gösterir ve önbelleklenen koşulun ikinci koşumda kaç giriş
okuduğunu sayar.
