How GitHub Docs' new search works

Bài tóm tắt GitHub 2023 2. Tăng trưởng Độ khó: Dễ

GitHub · 2023 · 2. Tăng trưởng · Độ khó: Dễ — bài gốc

Bối cảnh

  • Search của docs.github.com trước đây là index trong bộ nhớ của tiến trình Node.js (Express): cào hết văn bản (tiêu đề, heading, breadcrumb, nội dung), lưu ngay trong repo Git, sinh sẵn index serialize trên đĩa để nạp nhanh vào image Docker chạy trên Azure.
  • Theo GitHub, cách này "tạm ổn khi dữ liệu nhỏ", nhưng docs có 8 ngôn ngữ × 5 phiên bản, nên phải viết lại trên Elasticsearch.

Thay đổi chính

  • Chạy được ở máy local: mặc định middleware /api/search proxy sang server production; ai cần sửa search thì chạy Elasticsearch local và đặt ELASTICSEARCH_URL. Người chỉ sửa nội dung không phải cài gì.
  • Một query duy nhất chứa toàn bộ đặc tả xếp hạng, thay vì query chặt trước rồi query lỏng nếu ít kết quả. Thời gian chạy query trên server ổn định khoảng 20 ms; phần lớn độ trễ là mạng.
  • Ma trận boost: mỗi trường (title, headings, content) được index hai lần với hai analyzer: explicit (không stemming, không synonym) và thường (Snowball stemming). Kết hợp với match_phrase, match AND, match OR, fuzzy; mỗi ô có hệ số boost khác nhau (phrase × explicit × title cao nhất). Mục đích: kết quả khớp đúng chữ người gõ đứng trước kết quả chỉ khớp gốc từ (ví dụ working-directory không bị "Directories that work" lấn).
  • Khoảng 55% query là nhiều từ; query một từ bỏ được phần match_phrase.
  • Độ phổ biến: lấy pageview của top 1.000 URL, chuẩn hoá về 0–1, nhân điểm khớp với (1 + độ phổ biến), để trang phổ biến khớp kém hơn chút vẫn lên được nhưng không lấn trang khớp ở tiêu đề.
  • Việc tiếp theo nêu trong bài: synonym do người viết docs quản lý, tín hiệu "không được click", ngữ cảnh trang đang đứng.

Vì sao

  • Index trong bộ nhớ tiến trình không scale theo số ngôn ngữ × phiên bản; Elasticsearch tách search khỏi tiến trình web và cho công cụ xếp hạng phong phú.

Bài học cho SWE

  • Search trong bộ nhớ (hoặc ngay trên client, xem Mozilla 2021) là điểm khởi đầu hợp lý; chuyển sang một cụm search riêng khi dữ liệu nhân theo nhiều chiều (Hạ tầng tìm kiếm).
  • Giữ đường chạy local rẻ cho số đông (proxy sang production), chỉ người sửa search mới cần dựng cụm.
  • Gửi một query mô tả đủ ưu tiên thay vì chuỗi query rơi dần: ít round-trip, dễ suy luận.

Liên quan