# קונטיינר בסיסי ו-C# Client📖 שיעור

## מה זה?

עד עכשיו כתבנו שאילתות 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 גולמית

```bash
# 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
```

```csharp
// 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"));
```

```csharp
// 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](https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/introduction.html)

---

## תרגילים

### תרגיל 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 — איך רואים את הנתונים ומריצים שאילתות בממשק גרפי, לא רק בקוד.
