عميل Elasticsearch لـ TypeScript (@elastic/elasticsearch)
\n\nفي تطوير الويب الحديث، أصبح البحث النصي الكامل وتحليل البيانات جزءًا لا يتجزأ من العديد من التطبيقات. Elasticsearch هو نظام بحث موزع قوي مبني على Apache Lucene. للعمل معه من تطبيقات TypeScript (سواء على خادم Node.js أو في المتصفح)، يُستخدم العميل الرسمي @elastic/elasticsearch. في هذه المقالة، سنشرح بالتفصيل كيفية تثبيته وإعداده وإمكانياته الرئيسية.
ما هو @elastic/elasticsearch؟
\n\n@elastic/elasticsearch هو العميل الرسمي عالي الأداء لـ Elasticsearch، والمكتوب بلغة TypeScript. يوفر مجموعة كاملة من واجهات برمجة التطبيقات (API) للتفاعل مع مجموعة Elasticsearch، بما في ذلك:
- \n
- فهرسة وحذف المستندات \n
- البحث النصي الكامل مع دعم الاستعلامات المعقدة \n
- التجميعات لتحليل البيانات (التجميع، الإحصائيات) \n
- إدارة الفهارس والتعيين (Mapping) \n
- دعم تجمع الاتصالات، إعادة المحاولة، وتوزيع الحمل \n
بفضل الدعم الكامل لـ TypeScript، تحصل على الإكمال التلقائي، التحقق من الأنواع، والتوثيق مباشرة في بيئة التطوير المتكاملة (IDE).
\n\nالتثبيت
\n\nللبدء، قم بتثبيت الحزمة عبر npm أو yarn:
\n\nnpm install @elastic/elasticsearch\n# أو\nyarn add @elastic/elasticsearch\n\nإذا كنت تستخدم TypeScript، فلا حاجة لتثبيت أنواع إضافية - فهي مدمجة بالفعل في الحزمة.
\n\nالاتصال وإعداد العميل
\n\nقم بإنشاء نسخة من العميل، مع تحديد عنوان URL لمجموعة Elasticsearch الخاصة بك:
\n\nimport { Client } from '@elastic/elasticsearch';\n\nconst client = new Client({\n node: 'http://localhost:9200', // أو نقطة نهاية سحابية\n auth: {\n username: 'elastic',\n password: 'changeme'\n },\n // للإنتاج، يُوصى باستخدام TLS\n tls: {\n rejectUnauthorized: false // للتطوير فقط!\n }\n});\n\nللنشر السحابي (Elastic Cloud)، استخدم cloud.id و auth.apiKey:
const client = new Client({\n cloud: {\n id: 'my-cluster:dXMtZWFzdD...'\n },\n auth: {\n apiKey: 'base64EncodedApiKey'\n }\n});\n\nالعمليات الأساسية
\n\n1. فهرسة مستند
\n\nإضافة مستند جديد إلى الفهرس:
\n\ninterface Product {\n id: number;\n name: string;\n description: string;\n price: number;\n tags: string[];\n}\n\nasync function indexProduct(product: Product) {\n const response = await client.index({\n index: 'products',\n id: String(product.id),\n body: product,\n refresh: 'wait_for' // انتظار تحديث الفهرس\n });\n console.log('Document indexed:', response.result);\n}\n\nindexProduct({\n id: 1,\n name: 'لابتوب Lenovo ThinkPad',\n description: 'لابتوب قوي للتطوير',\n price: 1200,\n tags: ['إلكترونيات', 'لابتوبات']\n});\n\n2. البحث عن المستندات
\n\nبحث نصي كامل بسيط في حقل description:
async function searchProducts(query: string) {\n const response = await client.search({\n index: 'products',\n body: {\n query: {\n match: {\n description: query\n }\n },\n // التقسيم إلى صفحات\n from: 0,\n size: 10\n }\n });\n\n const hits = response.hits.hits.map(hit => hit._source);\n console.log('Found products:', hits);\n return hits;\n}\n\nsearchProducts('لابتوب تطوير');\n\n3. التجميعات
\n\nتجميع المنتجات حسب العلامات:
\n\nasync function aggregateByTags() {\n const response = await client.search({\n index: 'products',\n body: {\n size: 0, // لا نعيد المستندات نفسها\n aggs: {\n by_tag: {\n terms: {\n field: 'tags.keyword',\n size: 20\n }\n }\n