מה זה?

עד עכשיו כתבנו שאילתות JSON ישירות. אבל ב-API אמיתי (מיחידת ASP.NET Core), הקוד צריך לבנות ולשלוח שאילתות כאלה תוכנתית. פותרים את זה בשני שלבים: מריצים Elasticsearch כקונטיינר Docker (בדיוק כמו MongoDB/Kafka מיחידות קודמות), ומשתמשים בספריית לקוח C# רשמית שהופכת בניית שאילתות ל-API מוכר של אובייקטים, לא מחרוזות JSON ידניות.

מילות מפתח שחשוב לזכור

• Elasticsearch Container — הרצת Elasticsearch כקונטיינר Docker, בדיוק כמו MongoDB/Kafka שכבר תרגלנו

• Elastic.Clients.Elasticsearch — ספריית ה-.NET הרשמית לתקשורת עם Elasticsearch מ-C#

• Fluent API — סגנון כתיבה שמאפשר לבנות שאילתה עם שרשור מתודות קריא, במקום מחרוזת JSON גולמית

# Docker — running Elasticsearch as a container, like in the NoSQL unit
docker run -p 9200:9200 -e "discovery.type=single-node" -e "xpack.security.enabled=false" \
  docker.elastic.co/elasticsearch/elasticsearch:8.15.0
// C# Client — connection and Index setup
using Elastic.Clients.Elasticsearch;

var client = new ElasticsearchClient(new Uri("http://localhost:9200"));

// adding a document
var product = new Product { Name = "Adidas running shoes", Price = 349.90, Category = "Footwear" };
await client.IndexAsync(product, idx => idx.Index("products"));
// Query with Fluent API — instead of raw JSON
var response = await client.SearchAsync<Product>(s => s
    .Index("products")
    .Query(q => q
        .Bool(b => b
            .Must(m => m.Match(mm => mm.Field(f => f.Name).Query("shoes")))
            .Filter(f => f.Term(t => t.Field(ff => ff.Category.Suffix("keyword")).Value("Footwear")))
        )
    )
);

foreach (var hit in response.Documents)
{
    Console.WriteLine(hit.Name);
}

הסבר עיקרי

Container דומה לגמרי למה שכבר תרגלנו — הרצת Elasticsearch כ-Docker Container היא בדיוק אותו תהליך כמו MongoDB/Kafka מיחידה קודמת: docker run עם מיפוי פורט (9200, פורט ה-API הסטנדרטי של Elasticsearch), ומשתני סביבה (-e) להגדרות בסיסיות. שום דבר חדש מבחינת Docker עצמו.

Fluent API הופך JSON מקונן לקוד C# בטוח-טיפוסים — במקום לבנות מחרוזת JSON ידנית (מסוכן — שגיאות הקלדה לא נתפסות בקומפילציה), ה-Client נותן API שמדמה את מבנה השאילתה עם מתודות C# רגילות (Bool, Must, Filter, Match, Term) — הקומפיילר בודק את זה, בדיוק כמו LINQ. השאילתה ה-bool+must+filter מהשיעורים הקודמים “מתורגמת” ישירות לקוד C#.

IndexAsync/SearchAsync הם async — בדומה לכל קריאת רשת שכבר נתקלנו בה (HttpClient, MongoDB Driver, EF Core) — תקשורת עם Elasticsearch דרך הרשת, ולכן async/await הם ברירת המחדל, לא בונוס.

יתרונות

Docker Container נותן סביבת פיתוח זהה לכולם, בדיוק כמו MongoDB/Kafka; Fluent C# API בטוח-טיפוסים מונע שגיאות JSON שנתפסות רק בזמן ריצה; אינטגרציה ישירה עם מודלי C# קיימים (Product וכו’).

חסרונות

Fluent API עם שאילתות מורכבות מאוד (הרבה bool/aggs מקוננים) יכול להיות מסורבל לקריאה בהשוואה ל-JSON ישיר; דורש עדכון גרסת הספרייה בהתאמה לגרסת Elasticsearch עצמה.

נקודות חשובות

• Elasticsearch רץ כקונטיינר Docker, בדיוק כמו MongoDB/Kafka

• Elastic.Clients.Elasticsearch הוא ה-Client הרשמי ל-.NET

• Fluent API בונה שאילתות עם מתודות C# בטוחות-טיפוסים, במקום JSON גולמי

• IndexAsync/SearchAsync הם async, כמו כל תקשורת רשת אחרת שכבר נלמדה

טעויות נפוצות

• לשכוח xpack.security.enabled=false בסביבת פיתוח מקומית ולהיתקל בדרישת אימות לא-רצויה

• לבלבל בין שם ה-Index ב-Elasticsearch לשם המחלקה ב-C# — צריך למפות במפורש (idx.Index("products"))

• לנסות לגשת ל-Category כ-text בשאילתת Term במקום Category.Suffix("keyword") — אותה מלכודת מהשיעור השני, עכשיו בקוד C#

סיכום

Elasticsearch רץ כקונטיינר Docker, בדיוק כמו MongoDB/Kafka מהיחידה הקודמת — שום דבר חדש מבחינת Docker עצמו. Elastic.Clients.Elasticsearch נותן Fluent API בטוח-טיפוסים לבניית שאילתות מ-C#, במקום מחרוזות JSON גולמיות — כל מה שנלמד על match/term/bool/aggs “מתורגם” ישירות לקריאות מתודה C# מוכרות ובטוחות בקומפילציה.

דוקומנטציה רשמית

Elastic — .NET Client


תרגילים

תרגיל 1 — קונטיינר והוספת מסמך

המשימה: הריצו Elasticsearch ב-Docker, וכתבו קוד C# שמוסיף 3 מוצרים ל-Index products עם IndexAsync.

בדיקה: שאילתת _search ישירה (JSON, דרך curl/Kibana) מציגה את 3 המוצרים שנוספו מ-C#.

תרגיל 2 — שאילתה עם Fluent API

המשימה: כתבו קוד C# עם SearchAsync ו-Match שמחפש מוצר לפי שם, והדפיסו את התוצאות.

בדיקה: החיפוש מ-C# מחזיר תוצאות זהות למה שהיה מתקבל משאילתת JSON ישירה מקבילה.


פרויקט מסכם

המשימה: בנו SearchController ב-ASP.NET Core (מיחידה קודמת) שחושף חיפוש מוצרים דרך Elasticsearch.

דרישות:

  1. [HttpGet] endpoint שמקבל מונח חיפוש (query parameter) ומריץ match על שם המוצר
  2. שילוב עם filter אופציונלי לקטגוריה, אם סופקה
  3. IActionResult (מיחידת ASP.NET Core) שמחזיר את התוצאות כ-JSON

בדיקה: קריאה ל-GET api/search?term=נעליים מחזירה מוצרים תואמים; הוספת פרמטר קטגוריה מסננת נוסף.

מה בפרק הבא

בפרק הבא — Kibana: כלי הוויזואליזציה שמלווה את Elasticsearch — איך רואים את הנתונים ומריצים שאילתות בממשק גרפי, לא רק בקוד.