عميل Elasticsearch للغة Rust: elasticsearch-rs
\n\nElasticsearch هو نظام بحث وتحليل موزع وقوي، مبني على Apache Lucene. للتفاعل معه من تطبيقات Rust، يوجد عميل رسمي — elasticsearch-rs. توفر هذه المكتبة مجموعة كاملة من الأدوات للعمل مع REST API الخاص بـ Elasticsearch، بما في ذلك الفهرسة والبحث والتجميعات وإدارة الكتلة. في هذه المقالة، سنشرح بالتفصيل التثبيت والإعداد والإمكانيات الأساسية لـ elasticsearch-rs مع أمثلة على الكود.
\n\nما هو elasticsearch-rs؟
\nelasticsearch-rs هو عميل غير متزامن رسمي لـ Elasticsearch للغة Rust، تم تطويره بواسطة شركة Elastic. يعتمد على مكتبة عميل HTTP غير المتزامنة الشهيرة reqwest ويوفر واجهة برمجة تطبيقات آمنة من حيث الأنواع لجميع نقاط نهاية Elasticsearch. المزايا الرئيسية:
- \n
- دعم كامل لـ Elasticsearch 7.x و 8.x — جميع العمليات الأساسية: CRUD، البحث، التجميعات، إدارة الفهارس. \n
- غير متزامن — يستخدم async/await، مما يسمح بمعالجة فعالة للعديد من الطلبات. \n
- أمان من حيث الأنواع — هياكل الطلبات والاستجابات محددة بدقة، مما يقلل من أخطاء وقت التشغيل. \n
- تسلسل/إلغاء تسلسل تلقائي — عبر
serdeوserde_json. \n - دعم المصادقة — Basic Auth، مفاتيح API، SSL/TLS. \n
التثبيت
\nأضف التبعية إلى Cargo.toml:
[dependencies]\nelasticsearch = "8.14.0"\nserde = { version = "1.0", features = ["derive"] }\nserde_json = "1.0"\ntokio = { version = "1", features = ["full"] }\n\nالاتصال الأساسي
\nلنقم بإنشاء عميل يتصل بنسخة محلية من Elasticsearch:
\nuse elasticsearch::Elasticsearch;\nuse elasticsearch::http::transport::Transport;\nuse serde_json::json;\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn std::error::Error>> {\n let transport = Transport::single_node("http://localhost:9200")?;\n let client = Elasticsearch::new(transport);\n // التحقق من الاتصال\n let response = client.ping().send().await?;\n println!("Elasticsearch متاح: {}", response.status_code());\n Ok(())\n}\n\nالعمليات الأساسية: CRUD
\n\n1. فهرسة مستند
\nلنقم بإضافة مستند يحتوي على معلومات كتاب إلى الفهرس books:
#[derive(Serialize, Deserialize, Debug)]\nstruct Book {\n title: String,\n author: String,\n year: u16,\n isbn: String,\n}\n\nlet book = Book {\n title: "Rust في العمل".into(),\n author: "تيم ماكنمارا".into(),\n year: 2023,\n isbn: "978-5-4461-2345-6".into(),\n};\n\nlet response = client\n .index(IndexParts::IndexId("books", "1"))\n .body(json!(book))\n .send()\n .await?;\n\nprintln!("تمت فهرسة المستند: {:?}", response.body());\n\n2. الحصول على مستند
\nlet response = client\n .get(GetParts::IndexId("books", "1"))\n .send()\n .await?;\n\nif response.status_code().is_success() {\n let book: Book = response.json().await?;\n println!("تم العثور على المستند: {:?}", book);\n}\n\n3. تحديث مستند
\nlet response = client\n .update(UpdateParts::IndexId("books", "1"))\n .body(json!({\n "doc": { "year": 2024 }\n }))\n .send()\n .await?;\n\nprintln!("تم التحديث: {:?}", response.body());\n\n4. حذف مستند
\nlet response = client\n .delete(DeleteParts::IndexId("books", "1"))\n .send()\n .await?;\n\nprintln!("تم الحذف: {:?}", response.body());\n\nالبحث باستخدام Query DSL
\nلنقم بإجراء بحث نصي كامل في الحقل title:
use elasticsearch::SearchParts;\n\nl