# 按语义相似性搜索向量存储文档

{% openapi src="<https://1371168417-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4gvX7KIUy0DhcQETj8Ux%2Fuploads%2Fgit-blob-77b6137eeb641262ec8e531c78123c02b825b865%2Frememberizer_openapi.yml?alt=media&token=cce1ab0d-330f-4bed-b7da-5635aaf25472>" path="/vector-stores/{vector-store-id}/documents/search" method="get" %}
[rememberizer\_openapi.yml](https://1371168417-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4gvX7KIUy0DhcQETj8Ux%2Fuploads%2Fgit-blob-77b6137eeb641262ec8e531c78123c02b825b865%2Frememberizer_openapi.yml?alt=media\&token=cce1ab0d-330f-4bed-b7da-5635aaf25472)
{% endopenapi %}

## 示例请求

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

```bash
curl -X GET \
  "https://api.rememberizer.ai/api/v1/vector-stores/vs_abc123/documents/search?q=如何将我们的产品与第三方系统集成&n=5&prev_chunks=1&next_chunks=1" \
  -H "x-api-key: YOUR_API_KEY"
```

{% hint style="info" %}
将 `YOUR_API_KEY` 替换为您的实际向量存储 API 密钥，将 `vs_abc123` 替换为您的向量存储 ID。
{% endhint %}
{% endtab %}

{% tab title="JavaScript" %}

```javascript
const searchVectorStore = async (vectorStoreId, query, numResults = 5, prevChunks = 1, nextChunks = 1) => {
  const url = new URL(`https://api.rememberizer.ai/api/v1/vector-stores/${vectorStoreId}/documents/search`);
  url.searchParams.append('q', query);
  url.searchParams.append('n', numResults);
  url.searchParams.append('prev_chunks', prevChunks);
  url.searchParams.append('next_chunks', nextChunks);
  
  const response = await fetch(url.toString(), {
    method: 'GET',
    headers: {
      'x-api-key': 'YOUR_API_KEY'
    }
  });
  
  const data = await response.json();
  console.log(data);
};

searchVectorStore(
  'vs_abc123',
  '如何将我们的产品与第三方系统集成',
  5,
  1,
  1
);
```

{% hint style="info" %}
将 `YOUR_API_KEY` 替换为您的实际向量存储 API 密钥，将 `vs_abc123` 替换为您的向量存储 ID。
{% endhint %}
{% endtab %}

{% tab title="Python" %}

```python
import requests

def search_vector_store(vector_store_id, query, num_results=5, prev_chunks=1, next_chunks=1):
    headers = {
        "x-api-key": "YOUR_API_KEY"
    }
    
    params = {
        "q": query,
        "n": num_results,
        "prev_chunks": prev_chunks,
        "next_chunks": next_chunks
    }
    
    response = requests.get(
        f"https://api.rememberizer.ai/api/v1/vector-stores/{vector_store_id}/documents/search",
        headers=headers,
        params=params
    )
    
    data = response.json()
    print(data)

search_vector_store(
    'vs_abc123',
    '如何将我们的产品与第三方系统集成',
    5,
    1,
    1
)
```

{% hint style="info" %}
将 `YOUR_API_KEY` 替换为您的实际向量存储 API 密钥，将 `vs_abc123` 替换为您的向量存储 ID。
{% endhint %}
{% endtab %}

{% tab title="Ruby" %}

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

def search_vector_store(vector_store_id, query, num_results=5, prev_chunks=1, next_chunks=1)
  uri = URI("https://api.rememberizer.ai/api/v1/vector-stores/#{vector_store_id}/documents/search")
  params = {
    q: query,
    n: num_results,
    prev_chunks: prev_chunks,
    next_chunks: next_chunks
  }
  
  uri.query = URI.encode_www_form(params)
  
  request = Net::HTTP::Get.new(uri)
  request['x-api-key'] = 'YOUR_API_KEY'
  
  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_vector_store(
  'vs_abc123',
  '如何将我们的产品与第三方系统集成',
  5,
  1,
  1
)
```

{% hint style="info" %}
将 `YOUR_API_KEY` 替换为您的实际向量存储 API 密钥，将 `vs_abc123` 替换为您的向量存储 ID。
{% endhint %}
{% endtab %}
{% endtabs %}

## 路径参数

| 参数              | 类型  | 描述                    |
| --------------- | --- | --------------------- |
| vector-store-id | 字符串 | **必填。** 要搜索的向量存储的 ID。 |

## 查询参数

| 参数           | 类型  | 描述               |
| ------------ | --- | ---------------- |
| q            | 字符串 | **必填。** 搜索查询文本。  |
| n            | 整数  | 返回的结果数量。默认：10。   |
| t            | 数字  | 匹配阈值。默认：0.7。     |
| prev\_chunks | 整数  | 包含匹配块之前的块数。默认：0。 |
| next\_chunks | 整数  | 包含匹配块之后的块数。默认：0。 |

## 响应格式

```json
{
  "vector_store": {
    "id": "vs_abc123",
    "name": "产品文档"
  },
  "matched_chunks": [
    {
      "document": {
        "id": 1234,
        "name": "集成指南.pdf",
        "type": "application/pdf",
        "size": 250000,
        "indexed_on": "2023-06-15T10:30:00Z",
        "vector_store": "vs_abc123",
        "created": "2023-06-15T10:15:00Z",
        "modified": "2023-06-15T10:30:00Z"
      },
      "matched_content": "我们的产品为第三方系统提供了几种集成选项。主要方法是通过我们的 RESTful API，支持 OAuth2 认证。此外，您还可以使用我们提供的 Python、JavaScript 和 Java 的 SDK。",
      "distance": 0.123
    },
    // ... 更多匹配的内容
  ]
}
```

## 认证

此端点需要使用 `x-api-key` 头中的 API 密钥进行认证。

## 错误响应

| 状态码 | 描述                  |
| --- | ------------------- |
| 400 | 错误请求 - 缺少必需的参数或格式无效 |
| 401 | 未授权 - API 密钥无效或缺失   |
| 404 | 未找到 - 找不到向量存储       |
| 500 | 服务器内部错误             |

## 搜索优化技巧

### 上下文窗口

使用 `prev_chunks` 和 `next_chunks` 参数来控制每个匹配包含多少上下文：

* 将两者都设置为 0 以获得没有上下文的精确匹配
* 将两者都设置为 1-2 以获得具有最小上下文的匹配
* 将两者都设置为 3-5 以获得具有大量上下文的匹配

### 匹配阈值

`t` 参数控制匹配的过滤严格程度：

* 较高的值（例如，0.9）仅返回非常接近的匹配
* 较低的值（例如，0.5）返回更多种类的匹配
* 默认值（0.7）提供了一种平衡的方法

## 批量操作

对于高吞吐量的应用，Rememberizer 支持在向量存储上进行高效的批量操作。这些方法在处理多个搜索查询时优化性能。

### 批量搜索实现

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

```python
import requests
import time
import concurrent.futures

def batch_search_vector_store(vector_store_id, queries, num_results=5, batch_size=10):
    """
    对向量存储执行批量搜索
    
    参数:
        vector_store_id: 要搜索的向量存储的ID
        queries: 搜索查询字符串列表
        num_results: 每个查询的结果数量
        batch_size: 并行请求的数量
        
    返回:
        搜索结果列表
    """
    headers = {
        "x-api-key": "YOUR_API_KEY"
    }
    
    results = []
    
    # 分批处理以避免过载API
    for i in range(0, len(queries), batch_size):
        batch_queries = queries[i:i+batch_size]
        
        with concurrent.futures.ThreadPoolExecutor(max_workers=batch_size) as executor:
            futures = []
            
            for query in batch_queries:
                params = {
                    "q": query,
                    "n": num_results,
                    "prev_chunks": 1,
                    "next_chunks": 1
                }
                
                # 提交请求到线程池
                future = executor.submit(
                    requests.get,
                    f"https://api.rememberizer.ai/api/v1/vector-stores/{vector_store_id}/documents/search",
                    headers=headers,
                    params=params
                )
                futures.append(future)
            
            # 从所有未来对象收集结果
            for future in futures:
                response = future.result()
                if response.status_code == 200:
                    results.append(response.json())
                else:
                    results.append({"error": f"状态码失败: {response.status_code}"})
        
        # 在批次之间添加延迟以避免速率限制
        if i + batch_size < len(queries):
            time.sleep(1)
    
    return results

# 示例用法
queries = [
    "与 REST API 的集成",
    "认证协议",
    "如何部署到生产环境",
    "性能优化技术",
    "错误处理最佳实践"
]

search_results = batch_search_vector_store("vs_abc123", queries, num_results=3, batch_size=5)
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
/**
 * 对向量存储执行批量搜索
 * 
 * @param {string} vectorStoreId - 向量存储的 ID
 * @param {string[]} queries - 搜索查询列表
 * @param {Object} options - 配置选项
 * @returns {Promise<Array>} - 搜索结果列表
 */
async function batchSearchVectorStore(vectorStoreId, queries, options = {}) {
  const {
    numResults = 5,
    batchSize = 10,
    delayBetweenBatches = 1000,
    prevChunks = 1,
    nextChunks = 1,
    distanceThreshold = 0.7
  } = options;
  
  const results = [];
  const apiKey = 'YOUR_API_KEY';
  
  // 以批次处理以管理 API 负载
  for (let i = 0; i < queries.length; i += batchSize) {
    const batchQueries = queries.slice(i, i + batchSize);
    
    // 创建并行请求的 promise 数组
    const batchPromises = batchQueries.map(query => {
      const url = new URL(`https://api.rememberizer.ai/api/v1/vector-stores/${vectorStoreId}/documents/search`);
      url.searchParams.append('q', query);
      url.searchParams.append('n', numResults);
      url.searchParams.append('prev_chunks', prevChunks);
      url.searchParams.append('next_chunks', nextChunks);
      url.searchParams.append('t', distanceThreshold);
      
      return fetch(url.toString(), {
        method: 'GET',
        headers: {
          'x-api-key': apiKey
        }
      })
      .then(response => {
        if (response.ok) {
          return response.json();
        } else {
          return { error: `失败，状态码: ${response.status}` };
        }
      })
      .catch(error => {
        return { error: error.message };
      });
    });
    
    // 等待批次中的所有请求完成
    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 = [
  "与 REST API 的集成",
  "认证协议",
  "如何部署到生产环境",
  "性能优化技术",
  "错误处理最佳实践"
];

const options = {
  numResults: 3,
  batchSize: 5,
  delayBetweenBatches: 1000,
  prevChunks: 1,
  nextChunks: 1
};

batchSearchVectorStore("vs_abc123", queries, options)
  .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 vector_store_id [String] 向量存储的 ID
# @param queries [Array<String>] 搜索查询列表
# @param num_results [Integer] 每个查询的结果数量
# @param batch_size [Integer] 并行请求的数量
# @param delay_between_batches [Float] 批次之间等待的秒数
# @return [Array] 每个查询的搜索结果
def batch_search_vector_store(vector_store_id, queries, num_results: 5, batch_size: 10, delay_between_batches: 1.0)
  results = []
  api_key = 'YOUR_API_KEY'
  
  # 按批处理
  queries.each_slice(batch_size).with_index do |batch_queries, batch_index|
    # 创建一个线程池以进行并发执行
    pool = Concurrent::FixedThreadPool.new(batch_size)
    futures = []
    
    batch_queries.each do |query|
      # 将每个请求提交到线程池
      futures << Concurrent::Future.execute(executor: pool) do
        uri = URI("https://api.rememberizer.ai/api/v1/vector-stores/#{vector_store_id}/documents/search")
        params = {
          q: query,
          n: num_results,
          prev_chunks: 1,
          next_chunks: 1
        }
        
        uri.query = URI.encode_www_form(params)
        
        request = Net::HTTP::Get.new(uri)
        request['x-api-key'] = api_key
        
        http = Net::HTTP.new(uri.host, uri.port)
        http.use_ssl = true
        
        begin
          response = http.request(request)
          
          if response.code.to_i == 200
            JSON.parse(response.body)
          else
            { "error" => "状态码失败: #{response.code}" }
          end
        rescue => e
          { "error" => e.message }
        end
      end
    end
    
    # 收集所有 futures 的结果
    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 = [
  "与 REST API 的集成",
  "身份验证协议",
  "如何部署到生产环境", 
  "性能优化技术",
  "错误处理最佳实践"
]

results = batch_search_vector_store(
  "vs_abc123", 
  queries, 
  num_results: 3, 
  batch_size: 5
)

puts results
```

{% endtab %}
{% endtabs %}

### 批量操作的性能优化

在实现向量存储搜索的批量操作时，请考虑以下最佳实践：

1. **最佳批量大小**：对于大多数应用程序，平行处理 5-10 个查询在吞吐量和资源使用之间提供了良好的平衡。
2. **速率限制意识**：在批次之间包含延迟机制（通常为 1-2 秒），以避免触及 API 速率限制。
3. **错误处理**：为可能在批次中失败的单个查询实现强大的错误处理。
4. **连接管理**：对于高流量应用程序，实施连接池以减少开销。
5. **超时配置**：为每个请求设置适当的超时，以防止长时间运行的查询阻塞整个批次。
6. **结果处理**：考虑在结果可用时异步处理结果，而不是等待所有结果。
7. **监控**：跟踪平均响应时间和成功率等性能指标，以识别优化机会。

对于查询量非常大的生产应用程序，考虑实施一个队列系统和工作进程，以高效管理大批量。

此端点允许您使用语义相似性搜索您的向量存储。它返回与您的查询在概念上相关的文档，即使它们不包含确切的关键字。这使得它在自然语言查询和问答中尤其强大。
