# البحث عن الوثائق حسب التشابه الدلالي

{% openapi src="<https://4065521171-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FKV4TZLzR1jCpM5coRezn%2Fuploads%2Fgit-blob-77b6137eeb641262ec8e531c78123c02b825b865%2Frememberizer_openapi.yml?alt=media&token=5e84eb03-c48b-4980-9792-73172ea64dd4>" path="/documents/search/" method="get" %}
[rememberizer\_openapi.yml](https://4065521171-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FKV4TZLzR1jCpM5coRezn%2Fuploads%2Fgit-blob-77b6137eeb641262ec8e531c78123c02b825b865%2Frememberizer_openapi.yml?alt=media\&token=5e84eb03-c48b-4980-9792-73172ea64dd4)
{% endopenapi %}

## طلبات مثال

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X GET \
  "https://api.rememberizer.ai/api/v1/documents/search/?q=كيف%20أدمج%20Rememberizer%20مع%20تطبيقات%20مخصصة&n=5&from=2023-01-01T00:00:00Z&to=2023-12-31T23:59:59Z" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

{% hint style="info" %}
استبدل `YOUR_JWT_TOKEN` برمز JWT الفعلي الخاص بك.
{% endhint %}
{% endtab %}

{% tab title="JavaScript" %}

```javascript
const searchDocuments = async (query, numResults = 5, from = null, to = null) => {
  const url = new URL('https://api.rememberizer.ai/api/v1/documents/search/');
  url.searchParams.append('q', query);
  url.searchParams.append('n', numResults);
  
  if (from) {
    url.searchParams.append('from', from);
  }
  
  if (to) {
    url.searchParams.append('to', to);
  }
  
  const response = await fetch(url.toString(), {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer YOUR_JWT_TOKEN'
    }
  });
  
  const data = await response.json();
  console.log(data);
};

searchDocuments('كيف أدمج Rememberizer مع تطبيقات مخصصة', 5);
```

{% hint style="info" %}
استبدل `YOUR_JWT_TOKEN` برمز JWT الفعلي الخاص بك.
{% endhint %}
{% endtab %}

{% tab title="Python" %}

```python
import requests

def search_documents(query, num_results=5, from_date=None, to_date=None):
    headers = {
        "Authorization": "Bearer YOUR_JWT_TOKEN"
    }
    
    params = {
        "q": query,
        "n": num_results
    }
    
    if from_date:
        params["from"] = from_date
    
    if to_date:
        params["to"] = to_date
    
    response = requests.get(
        "https://api.rememberizer.ai/api/v1/documents/search/",
        headers=headers,
        params=params
    )
    
    data = response.json()
    print(data)

search_documents("كيف أدمج Rememberizer مع تطبيقات مخصصة", 5)
```

{% hint style="info" %}
استبدل `YOUR_JWT_TOKEN` برمز JWT الفعلي الخاص بك.
{% endhint %}
{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'net/http'
require 'uri'
require 'json'

def search_documents(query, num_results=5, from_date=nil, to_date=nil)
  uri = URI('https://api.rememberizer.ai/api/v1/documents/search/')
  params = {
    q: query,
    n: num_results
  }
  
  params[:from] = from_date if from_date
  params[:to] = to_date if to_date
  
  uri.query = URI.encode_www_form(params)
  
  request = Net::HTTP::Get.new(uri)
  request['Authorization'] = 'Bearer YOUR_JWT_TOKEN'
  
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  
  response = http.request(request)
  data = JSON.parse(response.body)
  puts data
end

search_documents("كيف أدمج Rememberizer مع تطبيقات مخصصة", 5)
```

{% hint style="info" %}
استبدل `YOUR_JWT_TOKEN` برمز JWT الفعلي الخاص بك.
{% endhint %}
{% endtab %}
{% endtabs %}

## معلمات الاستعلام

| المعلمة      | النوع    | الوصف                                                                                              |
| ------------ | -------- | -------------------------------------------------------------------------------------------------- |
| q            | سلسلة    | **مطلوب.** نص استعلام البحث (حتى 400 كلمة).                                                        |
| n            | عدد صحيح | عدد النتائج المراد إرجاعها. الافتراضي: 3. استخدم قيمًا أعلى (مثل 10) للحصول على نتائج أكثر شمولاً. |
| from         | سلسلة    | بداية نطاق الوقت للوثائق المراد البحث عنها، بتنسيق ISO 8601.                                       |
| to           | سلسلة    | نهاية نطاق الوقت للوثائق المراد البحث عنها، بتنسيق ISO 8601.                                       |
| prev\_chunks | عدد صحيح | عدد الأجزاء السابقة التي يجب تضمينها للسياق. الافتراضي: 2.                                         |
| next\_chunks | عدد صحيح | عدد الأجزاء التالية التي يجب تضمينها للسياق. الافتراضي: 2.                                         |

## تنسيق الاستجابة

```json
{
  "data_sources": [
    {
      "name": "Google Drive",
      "documents": 3
    },
    {
      "name": "Slack",
      "documents": 2
    }
  ],
  "matched_chunks": [
    {
      "document": {
        "id": 12345,
        "document_id": "1aBcD2efGhIjK3lMnOpQrStUvWxYz",
        "name": "وثائق واجهة برمجة تطبيقات Rememberizer.pdf",
        "type": "application/pdf",
        "path": "/Documents/Rememberizer/API Documentation.pdf",
        "url": "https://drive.google.com/file/d/1aBcD2efGhIjK3lMnOpQrStUvWxYz/view",
        "size": 250000,
        "created_time": "2023-05-10T14:30:00Z",
        "modified_time": "2023-06-15T09:45:00Z",
        "indexed_on": "2023-06-15T10:30:00Z",
        "integration": {
          "id": 101,
          "integration_type": "google_drive"
        }
      },
      "matched_content": "لدمج Rememberizer مع التطبيقات المخصصة، يمكنك استخدام تدفق مصادقة OAuth2 لتفويض تطبيقك للوصول إلى بيانات Rememberizer الخاصة بالمستخدم. بمجرد التفويض، يمكن لتطبيقك استخدام واجهات برمجة تطبيقات Rememberizer للبحث عن الوثائق، واسترجاع المحتوى، والمزيد.",
      "distance": 0.123
    },
    // ... المزيد من الأجزاء المتطابقة
  ],
  "message": "تمت عملية البحث بنجاح",
  "code": "success"
}
```

## نصائح تحسين البحث

### للإجابة على الأسئلة

عند البحث عن إجابة لسؤال، حاول صياغة استفسارك كما لو كان إجابة مثالية. على سبيل المثال:

بدلاً من: "ما هو تضمين المتجهات؟" حاول: "تضمين المتجهات هو تقنية تحول النص إلى متجهات عددية في فضاء عالي الأبعاد."

{% hint style="info" %}
لفهم أعمق لكيفية عمل تضمينات المتجهات ولماذا تعتبر هذه الطريقة في البحث فعالة، انظر [ما هي تضمينات المتجهات وقواعد بيانات المتجهات؟](https://docs.rememberizer.ai/ar/background/what-are-vector-embeddings-and-vector-databases)
{% endhint %}

### ضبط عدد النتائج

* ابدأ بـ `n=3` للحصول على نتائج سريعة وعالية الصلة
* زد إلى `n=10` أو أكثر للحصول على معلومات أكثر شمولاً
* إذا كانت نتائج البحث غير كافية، حاول زيادة معلمة `n`

### تصفية قائمة على الوقت

استخدم معلمات `from` و `to` للتركيز على الوثائق من فترات زمنية محددة:

* وثائق حديثة: قم بتعيين `from` إلى تاريخ حديث
* تحليل تاريخي: حدد نطاق تاريخي معين
* استبعاد المعلومات القديمة: قم بتعيين تاريخ `to` مناسب

## العمليات الجماعية

للتعامل بكفاءة مع كميات كبيرة من استعلامات البحث، يدعم Rememberizer العمليات الجماعية لتحسين الأداء وتقليل عبء استدعاءات واجهة برمجة التطبيقات.

### البحث الجماعي

{% tabs %}
{% tab title="Python" %}

```python
import requests
import time
import json
from concurrent.futures import ThreadPoolExecutor

def batch_search_documents(queries, num_results=5, batch_size=10):
    """
    إجراء عمليات بحث جماعية مع استعلامات متعددة
    
    Args:
        queries: قائمة من سلاسل استعلام البحث
        num_results: عدد النتائج التي يجب إرجاعها لكل استعلام
        batch_size: عدد الاستعلامات التي يجب معالجتها بالتوازي
    
    Returns:
        قائمة بنتائج البحث لكل استعلام
    """
    headers = {
        "Authorization": "Bearer YOUR_JWT_TOKEN",
        "Content-Type": "application/json"
    }
    
    results = []
    
    # معالجة الاستعلامات في دفعات
    for i in range(0, len(queries), batch_size):
        batch = queries[i:i+batch_size]
        
        # إنشاء مجموعة خيوط لإرسال الطلبات بالتوازي
        with ThreadPoolExecutor(max_workers=batch_size) as executor:
            futures = []
            
            for query in batch:
                params = {
                    "q": query,
                    "n": num_results
                }
                
                future = executor.submit(
                    requests.get,
                    "https://api.rememberizer.ai/api/v1/documents/search/",
                    headers=headers,
                    params=params
                )
                futures.append(future)
            
            # جمع النتائج عند الانتهاء
            for future in futures:
                response = future.result()
                results.append(response.json())
        
        # تحديد المعدل - التوقف بين الدفعات لتجنب تقييد واجهة برمجة التطبيقات
        if i + batch_size < len(queries):
            time.sleep(1)
    
    return results

# مثال على الاستخدام
queries = [
    "كيفية استخدام OAuth مع Rememberizer",
    "خيارات تكوين قاعدة بيانات المتجهات",
    "أفضل الممارسات للبحث الدلالي",
    # أضف المزيد من الاستعلامات حسب الحاجة
]

results = batch_search_documents(queries, num_results=3, batch_size=5)
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
/**
 * إجراء عمليات بحث جماعية مع استعلامات متعددة
 * 
 * @param {string[]} queries - قائمة بسلاسل استعلام البحث
 * @param {number} numResults - عدد النتائج التي يجب إرجاعها لكل استعلام
 * @param {number} batchSize - عدد الاستعلامات التي يجب معالجتها بالتوازي
 * @param {number} delayBetweenBatches - مللي ثانية للانتظار بين المجموعات
 * @returns {Promise<Array>} - قائمة بنتائج البحث لكل استعلام
 */
async function batchSearchDocuments(queries, numResults = 5, batchSize = 10, delayBetweenBatches = 1000) {
  const results = [];
  
  // معالجة الاستعلامات في مجموعات
  for (let i = 0; i < queries.length; i += batchSize) {
    const batch = queries.slice(i, i + batchSize);
    
    // إنشاء مصفوفة من الوعود للطلبات المتزامنة
    const batchPromises = batch.map(query => {
      const url = new URL('https://api.rememberizer.ai/api/v1/documents/search/');
      url.searchParams.append('q', query);
      url.searchParams.append('n', numResults);
      
      return fetch(url.toString(), {
        method: 'GET',
        headers: {
          'Authorization': 'Bearer YOUR_JWT_TOKEN'
        }
      }).then(response => response.json());
    });
    
    // الانتظار حتى تكتمل جميع الطلبات في المجموعة
    const batchResults = await Promise.all(batchPromises);
    results.push(...batchResults);
    
    // تحديد معدل الطلبات - التوقف بين المجموعات لتجنب تقييد واجهة برمجة التطبيقات
    if (i + batchSize < queries.length) {
      await new Promise(resolve => setTimeout(resolve, delayBetweenBatches));
    }
  }
  
  return results;
}

// مثال على الاستخدام
const queries = [
  "كيفية استخدام OAuth مع Rememberizer",
  "خيارات تكوين قاعدة بيانات المتجهات",
  "أفضل الممارسات للبحث الدلالي",
  // أضف المزيد من الاستعلامات حسب الحاجة
];

batchSearchDocuments(queries, 3, 5)
  .then(results => console.log(results))
  .catch(error => console.error('خطأ في البحث الجماعي:', error));
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'net/http'
require 'uri'
require 'json'
require 'concurrent'

# إجراء عمليات بحث جماعية باستخدام استعلامات متعددة
#
# @param queries [Array<String>] قائمة سلاسل استعلام البحث
# @param num_results [Integer] عدد النتائج التي يجب إرجاعها لكل استعلام
# @param batch_size [Integer] عدد الاستعلامات لمعالجتها بالتوازي
# @param delay_between_batches [Float] ثوانٍ للانتظار بين الدفعات
# @return [Array] قائمة نتائج البحث لكل استعلام
def batch_search_documents(queries, num_results = 5, batch_size = 10, delay_between_batches = 1.0)
  results = []
  
  # معالجة الاستعلامات في دفعات
  queries.each_slice(batch_size).with_index do |batch, batch_index|
    # إنشاء مجموعة خيوط للطلبات المتزامنة
    pool = Concurrent::FixedThreadPool.new(batch_size)
    futures = []
    
    batch.each do |query|
      futures << Concurrent::Future.execute(executor: pool) do
        uri = URI('https://api.rememberizer.ai/api/v1/documents/search/')
        params = {
          q: query,
          n: num_results
        }
        
        uri.query = URI.encode_www_form(params)
        
        request = Net::HTTP::Get.new(uri)
        request['Authorization'] = 'Bearer YOUR_JWT_TOKEN'
        
        http = Net::HTTP.new(uri.host, uri.port)
        http.use_ssl = true
        
        response = http.request(request)
        JSON.parse(response.body)
      end
    end
    
    # جمع النتائج من جميع الخيوط
    batch_results = futures.map(&:value)
    results.concat(batch_results)
    
    # تحديد المعدل - توقف بين الدفعات لتجنب تقييد واجهة برمجة التطبيقات
    if batch_index < (queries.length / batch_size.to_f).ceil - 1
      sleep(delay_between_batches)
    end
  end
  
  pool.shutdown
  results
end

# مثال على الاستخدام
queries = [
  "كيفية استخدام OAuth مع Rememberizer",
  "خيارات تكوين قاعدة بيانات المتجهات",
  "أفضل الممارسات للبحث الدلالي",
  # أضف المزيد من الاستفسارات حسب الحاجة
]

results = batch_search_documents(queries, 3, 5)
puts results
```

{% endtab %}
{% endtabs %}

### اعتبارات الأداء

عند تنفيذ عمليات الدفعات، ضع في اعتبارك هذه الممارسات الجيدة:

1. **حجم الدفعة الأمثل**: ابدأ بأحجام دفعات تتراوح بين 5-10 استفسارات واضبطها بناءً على خصائص أداء تطبيقك.
2. **تحديد المعدل**: قم بتضمين تأخيرات بين الدفعات لمنع تقليل سرعة واجهة برمجة التطبيقات. نقطة انطلاق جيدة هي 1 ثانية بين الدفعات.
3. **معالجة الأخطاء**: نفذ معالجة أخطاء قوية لإدارة الطلبات الفاشلة ضمن الدفعات.
4. **إدارة الموارد**: راقب استخدام الموارد على جانب العميل، خاصة مع أحجام الدفعات الكبيرة، لمنع استهلاك الذاكرة بشكل مفرط.
5. **معالجة الاستجابة**: قم بمعالجة نتائج الدفعة بشكل غير متزامن عند الإمكان لتحسين تجربة المستخدم.

بالنسبة للتطبيقات ذات الحجم الكبير، ضع في اعتبارك تنفيذ نظام قائمة لإدارة أعداد كبيرة من طلبات البحث بكفاءة.

توفر هذه النقطة واجهة قوية للبحث الدلالي عبر قاعدة معرفتك بالكامل. تستخدم تضمينات المتجهات للعثور على المحتوى بناءً على المعنى بدلاً من المطابقات الدقيقة للكلمات الرئيسية.
