GoDasturchi
Search Indexing

Search Indexing

Qidiruv indeksi

Kitobning oxiridagi "indeks" sahifasini tasavvur qiling: u sizga "microservices" so'zi qaysi SAHIFALARDA uchrashini AYTADI, siz esa BUTUN kitobni sahifama-sahifa o'qib chiqishga hojat qolmaydi. Inverted index (teskari indeks) — Log Aggregator'da xuddi shu vazifani bajaradi: har bir SO'Z uchun, o'sha so'z uchraydigan barcha log yozuvlarining RO'YXATINI oldindan tayyorlab qo'yadi.

example.go
package main

import (
	"fmt"
	"strings"
)

type LogEntry struct {
	Message string
}

// SearchIndex — so'z -> shu so'z uchraydigan log yozuvlarining INDEKSLARI
type SearchIndex struct {
	index map[string][]int
}

func NewSearchIndex() *SearchIndex {
	return &SearchIndex{index: make(map[string][]int)}
}

// Add — bitta log yozuvini indeksga qo'shadi
func (si *SearchIndex) Add(entryIndex int, message string) {
	words := strings.Fields(strings.ToLower(message))
	for _, word := range words {
		si.index[word] = append(si.index[word], entryIndex)
	}
}

// Search — berilgan so'z uchraydigan barcha yozuv indekslarini qaytaradi
func (si *SearchIndex) Search(word string) []int {
	return si.index[strings.ToLower(word)]
}

func main() {
	si := NewSearchIndex()
	si.Add(0, "to'lov muvaffaqiyatsiz")
	si.Add(1, "foydalanuvchi ro'yxatdan o'tdi")
	si.Add(2, "to'lov qabul qilindi")

	fmt.Println(si.Search("to'lov"))
}

si.index[word] = append(si.index[word], entryIndex) — "Maps with Slice Values" darsida ko'rgan naqsh: har bir so'z KALIT sifatida, unga tegishli BARCHA indekslar esa QIYMAT (slice) sifatida saqlanadi. Agar so'z hali xaritada YO'Q bo'lsa, appendning nil slice bilan ham TO'G'RI ishlashi (Go'ning xususiyati) tufayli, kod QO'SHIMCHA tekshiruvsiz ishlaydi.

Bu yondashuvning KUCHI: agar loglar SONI (masalan million) katta bo'lsa ham, Search("to'lov") BARCHA million logni SANAB o'tirmaydi — u to'g'ridan-to'g'ri index["to'lov"]ga MUROJAAT qiladi, bu — xaritaning O(1) tezligidagi qidiruv xususiyati. Bu — millionlab yozuv orasida MILLISEKUNDLARDA qidirish imkonini beradigan asosiy g'oya.

>_ Exercise

SearchIndex'ga bir nechta so'z bo'yicha KESISHUVCHI (AND) qidiruv qo'shing.

  • SearchAll(words []string) []int metodini yozing: HAR BIR so'zda ham uchraydigan indekslarni toping (kesishma)
  • Bo'sh natija uchun nil qaytaring; kesishmani hisoblashda birinchi so'z natijasidan boshlang
  • "to'lov muvaffaqiyatsiz", "tizim xatosi", "to'lov qabul qilindi" (indeks 0,1,2) qo'shing
  • SearchAll([]string{"to'lov"}) uzunligini chop eting

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

Inverted index — har bir so'z uchun uni o'z ichiga olgan yozuvlar ro'yxatini oldindan tayyorlab, million-million log orasida ham millisekundlarda qidirish imkonini beradi.

NEXT UP

Query Language

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

Search Indexing

Qidiruv indeksi

Kitobning oxiridagi "indeks" sahifasini tasavvur qiling: u sizga "microservices" so'zi qaysi SAHIFALARDA uchrashini AYTADI, siz esa BUTUN kitobni sahifama-sahifa o'qib chiqishga hojat qolmaydi. Inverted index (teskari indeks) — Log Aggregator'da xuddi shu vazifani bajaradi: har bir SO'Z uchun, o'sha so'z uchraydigan barcha log yozuvlarining RO'YXATINI oldindan tayyorlab qo'yadi.

example.go
package main

import (
	"fmt"
	"strings"
)

type LogEntry struct {
	Message string
}

// SearchIndex — so'z -> shu so'z uchraydigan log yozuvlarining INDEKSLARI
type SearchIndex struct {
	index map[string][]int
}

func NewSearchIndex() *SearchIndex {
	return &SearchIndex{index: make(map[string][]int)}
}

// Add — bitta log yozuvini indeksga qo'shadi
func (si *SearchIndex) Add(entryIndex int, message string) {
	words := strings.Fields(strings.ToLower(message))
	for _, word := range words {
		si.index[word] = append(si.index[word], entryIndex)
	}
}

// Search — berilgan so'z uchraydigan barcha yozuv indekslarini qaytaradi
func (si *SearchIndex) Search(word string) []int {
	return si.index[strings.ToLower(word)]
}

func main() {
	si := NewSearchIndex()
	si.Add(0, "to'lov muvaffaqiyatsiz")
	si.Add(1, "foydalanuvchi ro'yxatdan o'tdi")
	si.Add(2, "to'lov qabul qilindi")

	fmt.Println(si.Search("to'lov"))
}

si.index[word] = append(si.index[word], entryIndex) — "Maps with Slice Values" darsida ko'rgan naqsh: har bir so'z KALIT sifatida, unga tegishli BARCHA indekslar esa QIYMAT (slice) sifatida saqlanadi. Agar so'z hali xaritada YO'Q bo'lsa, appendning nil slice bilan ham TO'G'RI ishlashi (Go'ning xususiyati) tufayli, kod QO'SHIMCHA tekshiruvsiz ishlaydi.

Bu yondashuvning KUCHI: agar loglar SONI (masalan million) katta bo'lsa ham, Search("to'lov") BARCHA million logni SANAB o'tirmaydi — u to'g'ridan-to'g'ri index["to'lov"]ga MUROJAAT qiladi, bu — xaritaning O(1) tezligidagi qidiruv xususiyati. Bu — millionlab yozuv orasida MILLISEKUNDLARDA qidirish imkonini beradigan asosiy g'oya.

>_ Exercise

SearchIndex'ga bir nechta so'z bo'yicha KESISHUVCHI (AND) qidiruv qo'shing.

  • SearchAll(words []string) []int metodini yozing: HAR BIR so'zda ham uchraydigan indekslarni toping (kesishma)
  • Bo'sh natija uchun nil qaytaring; kesishmani hisoblashda birinchi so'z natijasidan boshlang
  • "to'lov muvaffaqiyatsiz", "tizim xatosi", "to'lov qabul qilindi" (indeks 0,1,2) qo'shing
  • SearchAll([]string{"to'lov"}) uzunligini chop eting

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

Inverted index — har bir so'z uchun uni o'z ichiga olgan yozuvlar ro'yxatini oldindan tayyorlab, million-million log orasida ham millisekundlarda qidirish imkonini beradi.

NEXT UP

Query Language