> ## Documentation Index
> Fetch the complete documentation index at: https://cndoc-langchain.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Oracle AI 向量搜索 - 集成

> 使用 LangChain Python 与 Oracle AI 向量搜索 - 向量存储进行集成。

Oracle AI 数据库支持通过**含义**（语义）而不仅仅是关键词来查询数据的 AI 工作负载。它将**非结构化内容的语义搜索**与**业务数据的关系型过滤**结合在一个系统中——因此您可以构建检索工作流（如 RAG），而无需引入单独的向量数据库或将数据分散在多个平台上。

本指南演示如何使用 `OracleVS`（用于 Oracle AI 向量搜索的 LangChain 向量存储集成）来：

* 将文档和嵌入向量摄入到 Oracle 中
* 运行相似性搜索
* 创建 HNSW 和 IVF 索引
* 应用元数据过滤器进行高级检索
* 在 Oracle 数据库 26ai 中启用混合搜索（关键词 + 语义）
* 使用 Oracle Text 运行全文搜索

### 先决条件

安装 `langchain-oracledb`。`python-oracledb` 驱动程序将作为依赖项自动安装。

<CodeGroup>
  ```bash pip theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  pip install -qU langchain-oracledb
  ```

  ```bash uv theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  uv add langchain-oracledb
  ```
</CodeGroup>

### 连接到 Oracle 数据库

以下示例代码将展示如何连接到 Oracle 数据库。默认情况下，python-oracledb 以“Thin”模式运行，该模式直接连接到 Oracle 数据库。此模式不需要 Oracle 客户端库。但是，当 python-oracledb 使用它们时，可以使用一些额外的功能。当使用 Oracle 客户端库时，python-oracledb 被称为处于“Thick”模式。两种模式都具有全面的功能，支持 Python 数据库 API v2.0 规范。请参阅以下[指南](https://python-oracledb.readthedocs.io/en/latest/user_guide/appendix_a.html#featuresummary)，了解每种模式支持的功能。如果您无法使用 thin 模式，可能需要切换到 thick 模式。

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import oracledb

# 请更新您的用户名、密码、主机名、端口和服务名
username = "<username>"
password = "<password>"
dsn = "<hostname>:<port>/<service_name>"

connection = oracledb.connect(user=username, password=password, dsn=dsn)
print("连接成功！")
```

### 导入所需的依赖项

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain_oracledb.vectorstores import oraclevs
from langchain_oracledb.vectorstores.oraclevs import OracleVS
from langchain_community.vectorstores.utils import DistanceStrategy
from langchain_core.documents import Document
from langchain_huggingface import HuggingFaceEmbeddings
```

### 加载文档

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
# 定义一个文档列表（以下示例是来自 Oracle 概念手册的 5 个随机文档）

documents_json_list = [
    {
        "id": "cncpt_15.5.3.2.2_P4",
        "text": "如果任何先前问题的答案是“是”，则数据库停止搜索并从指定的表空间分配空间；否则，从数据库默认共享临时表空间分配空间。",
        "link": "https://docs.oracle.com/en/database/oracle/oracle-database/23/cncpt/logical-storage-structures.html#GUID-5387D7B2-C0CA-4C1E-811B-C7EB9B636442",
    },
    {
        "id": "cncpt_15.5.5_P1",
        "text": "只要数据库处于打开状态，表空间可以是联机的（可访问）或脱机的（不可访问）。\n表空间通常是联机的，以便其数据可供用户使用。SYSTEM 表空间和临时表空间不能脱机。",
        "link": "https://docs.oracle.com/en/database/oracle/oracle-database/23/cncpt/logical-storage-structures.html#GUID-D02B2220-E6F5-40D9-AFB5-BC69BCEF6CD4",
    },
    {
        "id": "cncpt_22.3.4.3.1_P2",
        "text": "数据库存储 LOB 的方式与其他数据类型不同。创建 LOB 列会隐式创建一个 LOB 段和一个 LOB 索引。包含 LOB 段和 LOB 索引（它们始终存储在一起）的表空间可能与包含该表的表空间不同。\n有时数据库可以将少量 LOB 数据存储在表本身中，而不是存储在单独的 LOB 段中。",
        "link": "https://docs.oracle.com/en/database/oracle/oracle-database/23/cncpt/concepts-for-database-developers.html#GUID-3C50EAB8-FC39-4BB3-B680-4EACCE49E866",
    },
    {
        "id": "cncpt_22.3.4.3.1_P3",
        "text": "LOB 段以称为块的片段存储数据。块是一组逻辑上连续的数据块，是 LOB 的最小分配单元。表中的一行存储一个称为 LOB 定位器的指针，该指针指向 LOB 索引。当查询表时，数据库使用 LOB 索引来快速定位 LOB 块。",
        "link": "https://docs.oracle.com/en/database/oracle/oracle-database/23/cncpt/concepts-for-database-developers.html#GUID-3C50EAB8-FC39-4BB3-B680-4EACCE49E866",
    },
]
```

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
# 创建 LangChain 文档

documents_langchain = []

for doc in documents_json_list:
    metadata = {"id": doc["id"], "link": doc["link"]}
    doc_langchain = Document(page_content=doc["text"], metadata=metadata)
    documents_langchain.append(doc_langchain)
```

### 使用不同的距离度量创建向量存储

首先，我们将创建三个向量存储，每个使用不同的距离函数。由于我们尚未在其中创建索引，它们现在只会创建表。稍后我们将使用这些向量存储来创建 HNSW 索引。要了解更多关于 Oracle AI 向量搜索支持的不同类型索引的信息，请参阅以下[指南](https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/manage-different-categories-vector-indexes.html)。

您可以手动连接到 Oracle 数据库，您将看到三个表：
`Documents_DOT`、`Documents_COSINE` 和 `Documents_EUCLIDEAN`。

然后我们将创建三个额外的表 `Documents_DOT_IVF`、`Documents_COSINE_IVF` 和 `Documents_EUCLIDEAN_IVF`，这些表将用于在表上创建 IVF 索引，而不是 HNSW 索引。

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
# 使用不同的距离策略将文档摄入到 Oracle 向量存储中

# 当使用我们的 API 调用时，首先通过 from_documents() 使用文档子集初始化您的向量存储，
# 然后使用 add_texts() 增量添加更多文档。
# 这种方法可以防止系统过载并确保高效的文档处理。

model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2")

vector_store_dot = OracleVS.from_documents(
    documents_langchain,
    model,
    client=connection,
    table_name="Documents_DOT",
    distance_strategy=DistanceStrategy.DOT_PRODUCT,
)
vector_store_max = OracleVS.from_documents(
    documents_langchain,
    model,
    client=connection,
    table_name="Documents_COSINE",
    distance_strategy=DistanceStrategy.COSINE,
)
vector_store_euclidean = OracleVS.from_documents(
    documents_langchain,
    model,
    client=connection,
    table_name="Documents_EUCLIDEAN",
    distance_strategy=DistanceStrategy.EUCLIDEAN_DISTANCE,
)

# 使用不同的距离策略将文档摄入到 Oracle 向量存储中
vector_store_dot_ivf = OracleVS.from_documents(
    documents_langchain,
    model,
    client=connection,
    table_name="Documents_DOT_IVF",
    distance_strategy=DistanceStrategy.DOT_PRODUCT,
)
vector_store_max_ivf = OracleVS.from_documents(
    documents_langchain,
    model,
    client=connection,
    table_name="Documents_COSINE_IVF",
    distance_strategy=DistanceStrategy.COSINE,
)
vector_store_euclidean_ivf = OracleVS.from_documents(
    documents_langchain,
    model,
    client=connection,
    table_name="Documents_EUCLIDEAN_IVF",
    distance_strategy=DistanceStrategy.EUCLIDEAN_DISTANCE,
)
```

### 文本的添加和删除操作，以及基本的相似性搜索

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
def manage_texts(vector_stores):
    """
    向每个向量存储添加文本，演示重复添加的错误处理，
    并执行文本删除。展示每个向量存储的相似性搜索和索引创建。

    参数：
    - vector_stores (list): OracleVS 实例列表。
    """
    texts = ["Rohan", "Shailendra"]
    metadata = [
        {"id": "100", "link": "Document Example Test 1"},
        {"id": "101", "link": "Document Example Test 2"},
    ]

    for i, vs in enumerate(vector_stores, start=1):
        # 添加文本
        try:
            vs.add_texts(texts, metadata)
            print(f"\n\n\n向量存储 {i} 添加文本完成\n\n\n")
        except Exception as ex:
            print(f"\n\n\n向量存储 {i} 重复添加的预期错误\n\n\n")

        # 使用 'id' 的值删除文本
        vs.delete([metadata[0]["id"]])
        print(f"\n\n\n向量存储 {i} 删除文本完成\n\n\n")

        # 相似性搜索
        results = vs.similarity_search("LOB 在 Oracle 数据库中如何存储", 2)
        print(f"\n\n\n向量存储 {i} 的相似性搜索结果：{results}\n\n\n")


vector_store_list = [
    vector_store_dot,
    vector_store_max,
    vector_store_euclidean,
    vector_store_dot_ivf,
    vector_store_max_ivf,
    vector_store_euclidean_ivf,
]
manage_texts(vector_store_list)
```

### 使用特定参数创建索引

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
def create_search_indices(connection):
    """
    为向量存储创建搜索索引，每个索引都根据其距离策略定制了特定参数。
    """
    # DOT_PRODUCT 策略的索引
    # 注意我们正在使用默认参数创建 HNSW 索引
    # 这将默认创建一个具有 8 个并行工作线程的 HNSW 索引，并使用 Oracle AI 向量搜索使用的默认精度
    oraclevs.create_index(
        connection,
        vector_store_dot,
        params={"idx_name": "hnsw_idx1", "idx_type": "HNSW"},
    )

    # COSINE 策略的索引，具有特定参数
    # 注意我们正在创建一个具有 16 个并行线程且目标精度规范为 97% 的 HNSW 索引
    oraclevs.create_index(
        connection,
        vector_store_max,
        params={
            "idx_name": "hnsw_idx2",
            "idx_type": "HNSW",
            "accuracy": 97,
            "parallel": 16,
        },
    )

    # EUCLIDEAN_DISTANCE 策略的索引，具有特定参数
    # 注意我们正在通过指定高级用户参数（neighbors = 64 和 efConstruction = 100）来创建 HNSW 索引
    oraclevs.create_index(
        connection,
        vector_store_euclidean,
        params={
            "idx_name": "hnsw_idx3",
            "idx_type": "HNSW",
            "neighbors": 64,
            "efConstruction": 100,
        },
    )

    # DOT_PRODUCT 策略的索引，具有特定参数
    # 注意我们正在使用默认参数创建 IVF 索引
    # 这将默认创建一个具有 8 个并行工作线程的 IVF 索引，并使用 Oracle AI 向量搜索使用的默认精度
    oraclevs.create_index(
        connection,
        vector_store_dot_ivf,
        params={
            "idx_name": "ivf_idx1",
            "idx_type": "IVF",
        },
    )

    # COSINE 策略的索引，具有特定参数
    # 注意我们正在创建一个具有 32 个并行线程且目标精度规范为 90% 的 IVF 索引
    oraclevs.create_index(
        connection,
        vector_store_max_ivf,
        params={
            "idx_name": "ivf_idx2",
            "idx_type": "IVF",
            "accuracy": 90,
            "parallel": 32,
        },
    )

    # EUCLIDEAN_DISTANCE 策略的索引，具有特定参数
    # 注意我们正在通过指定高级用户参数 neighbor_part = 64 来创建 IVF 索引
    oraclevs.create_index(
        connection,
        vector_store_euclidean_ivf,
        params={"idx_name": "ivf_idx3", "idx_type": "IVF", "neighbor_part": 64},
    )

    print("索引创建完成。")


create_search_indices(connection)
```

### 高级搜索

Oracle 数据库 23ai 支持预过滤、过滤中和后过滤，以增强 AI 向量搜索功能。这些过滤机制允许用户在执行向量相似性搜索之前、期间和之后应用约束，从而提高搜索性能和准确性。

关于 Oracle 23ai 中过滤的关键点：

1. 预过滤
   应用传统 SQL 过滤器，在执行向量相似性搜索之前减少数据集。
   通过限制 AI 算法处理的数据量来帮助提高效率。
2. 过滤中
   利用 AI 向量搜索直接在向量嵌入上执行相似性搜索，使用优化的索引和算法。
   无需完整数据集扫描即可根据向量相似性高效过滤结果。
3. 后过滤
   在向量相似性搜索之后应用额外的 SQL 过滤以细化结果。
   允许根据业务逻辑或额外的元数据条件进行进一步细化。

**为什么这很重要？**

* 性能优化：预过滤显著减少查询执行时间，使在海量数据集上的搜索更高效。
* 准确性增强：过滤中确保向量搜索在语义上有意义，提高搜索结果的质量。

#### 过滤器详情

`OracleVS` 支持一组过滤器，可以使用 `filter` 参数应用于 `metadata` 字段。这些过滤器允许您根据各种标准选择和细化数据。

**可用的过滤器运算符：**

| 运算符              | 描述                                 |
| ---------------- | ---------------------------------- |
| `\$exists`       | 字段存在。                              |
| `\$eq`           | 字段值等于操作数值 (`=`)。                   |
| `\$ne`           | 字段存在且值不等于操作数值 (`!=`)。              |
| `\$gt`           | 字段值大于操作数值 (`>`)。                   |
| `\$lt`           | 字段值小于操作数值 (`<`)。                   |
| `\$gte`          | 字段值大于或等于操作数值 (`>=`)。               |
| `\$lte`          | 字段值小于或等于操作数值 (`<=`)。               |
| `\$between`      | 字段值介于操作数数组中的两个值之间（或等于）。            |
| `\$startsWith`   | 字段值以操作数值开头。                        |
| `\$hasSubstring` | 字段值包含操作数作为子字符串。                    |
| `\$instr`        | 字段值包含操作数作为子字符串。                    |
| `\$regex`        | 字段值匹配给定的正则表达式模式。                   |
| `\$like`         | 字段值匹配操作数模式（使用类 SQL 语法）。            |
| `\$in`           | 字段值等于操作数数组中的至少一个值。                 |
| `\$nin`          | 字段存在，但其值不等于操作数数组中的任何值，或者字段不存在。     |
| `\$all`          | 字段值是一个数组，包含操作数数组中的所有项，或匹配单个操作数的标量。 |

* 您可以使用逻辑运算符组合这些过滤器：

| 逻辑运算符   | 描述   |
| ------- | ---- |
| `\$and` | 逻辑与  |
| `\$or`  | 逻辑或  |
| `\$nor` | 逻辑或非 |

**过滤器示例：**

```json theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{
  "age": 65,
  "name": {"$regex": "*rk"},
  "$or": [
    {
      "$and": [
        {"name": "Jason"},
        {"drinks": {"$in": ["tea", "soda"]}}
      ]
    },
    {
      "$nor": [
        {"age": {"$lt": 65}},
        {"name": "Jason"}
      ]
    }
  ]
}
```

**其他使用提示：**

* 当对象中的所有过滤器都必须满足时，您可以省略 `$and`。以下两种写法是等效的：

```json theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{ "$and": [
    { "name": { "$startsWith": "Fred" } },
    { "salary": { "$gt": 10000, "$lte": 20000 } }
]}
```

```json theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{
  "name": { "$startsWith": "Fred" },
  "salary": { "$gt": 10000, "$lte": 20000 }
}
```

* `$not` 子句可以否定比较运算符：

```json theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{ "address.zip": { "$not": { "$eq": "90001" } } }
```

* 使用 `field: scalar` 等同于 `field: { "$eq": scalar }`：

```json theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{ "animal": "cat" }
```

有关更多过滤器示例，请参阅[测试规范](https://github.com/oracle/langchain-oracle/blob/main/libs/oracledb/tests/integration_tests/vectorstores/test_oraclevs.py)。

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
# 创建索引后进行高级搜索
def conduct_advanced_searches(vector_stores):
    query = "LOB 在 Oracle 数据库中如何存储"
    # 构建一个过滤器，用于直接与文档元数据进行比较
    # 此过滤器旨在包含元数据 'id' 恰好为 '2' 的文档
    db_filter = {
        "$and": [
            {"id": "101"},  # 过滤条件
            {
                "$or": [  # 过滤组
                    {"status": "approved"},
                    {"link": "Document Example Test 2"},
                    {
                        "$and": [  # 嵌套过滤组
                            {"status": "approved"},
                            {"link": "Document Example Test 2"},
                        ]
                    },
                ]
            },
        ]
    }

    for i, vs in enumerate(vector_stores, start=1):
        print(f"\n--- 向量存储 {i} 高级搜索 ---")
        # 不带过滤器的相似性搜索
        print("\n不带过滤器的相似性搜索结果：")
        print(vs.similarity_search(query, 2))

        # 带过滤器的相似性搜索
        print("\n带过滤器的相似性搜索结果：")
        print(vs.similarity_search(query, 2, filter=db_filter))

        # 带相关性分数的相似性搜索
        print("\n带相关性分数的相似性搜索：")
        print(vs.similarity_search_with_score(query, 2))

        # 带过滤器的相关性分数相似性搜索
        print("\n带过滤器的相关性分数相似性搜索：")
        print(vs.similarity_search_with_score(query, 2, filter=db_filter))

        # 最大边际相关性搜索
        print("\n最大边际相关性搜索结果：")
        print(vs.max_marginal_relevance_search(query, 2, fetch_k=20, lambda_mult=0.5))

        # 带过滤器的最大边际相关性搜索
        print("\n带过滤器的最大边际相关性搜索结果：")
        print(
            vs.max_marginal_relevance_search(
                query, 2, fetch_k=20, lambda_mult=0.5, filter=db_filter
            )
        )


conduct_advanced_searches(vector_store_list)
```

### 混合搜索

Oracle 数据库 26ai 支持混合搜索，将关键词（全文）和语义（向量）搜索结合到单一的检索功能中。`langchain-oracledb` 集成公开了：

* `OracleVectorizerPreference`：创建一个数据库端的向量化器偏好，供混合索引使用。
* `create_hybrid_index` / `acreate_hybrid_index`：创建一个混合向量索引。
* `OracleHybridSearchRetriever`：在 `OracleVS` 表上执行关键词、语义或混合检索。

#### 先决条件和模型配置

使用混合搜索时，请使用 `OracleEmbeddings` 配置您的 `OracleVS`，以便向量化器偏好与嵌入配置完全匹配。您可以通过 `OracleVectorizerPreference` 提供额外参数来进一步调整混合向量索引。有关详细信息，请参阅[文档](https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/create_preference.html)。

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain_core.documents import Document
from langchain_oracledb.embeddings import OracleEmbeddings
from langchain_oracledb.vectorstores.oraclevs import OracleVS
from langchain_oracledb.retrievers.hybrid_search import (
    OracleVectorizerPreference,
    create_hybrid_index,
    OracleHybridSearchRetriever,
)

# 使用 OracleEmbeddings（显示数据库驻留模型）
embeddings = OracleEmbeddings(conn=connection, params={"provider": "database", "model": "DB_MODEL"})

# 创建/加载您的向量存储
vs = OracleVS(connection, table_name="DOCS", embedding_function=embeddings)

# 创建一个向量化器偏好
pref = OracleVectorizerPreference.create_preference(
    vector_store=vs, preference_name="PREF_DOCS"
)

# 创建一个混合向量索引
create_hybrid_index(
    connection,
    idx_name="IDX_DOCS_HYB",
    vectorizer_preference=pref
)

# 构建检索器并搜索
retriever = OracleHybridSearchRetriever(
    vector_store=vs,
    idx_name="IDX_DOCS_HYB",
    search_mode="hybrid",     # "hybrid" | "keyword" | "semantic"
    k=5,
    return_scores=True,       # 在元数据中包含 score, text_score, vector_score
)

docs = retriever.invoke("高级套餐的退款政策")
for d in docs:
    print(d.page_content, d.metadata.get("score"), d.metadata.get("text_score"), d.metadata.get("vector_score"))

# 使用完偏好后可选清理：
# pref.drop_preference()
```

*替代方案* 在不使用显式偏好情况下创建索引：

* 如果您不想管理命名的偏好，请改为传递 `vector_store`。该函数将创建一个临时偏好，构建索引，然后自动删除该偏好。

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
create_hybrid_index(
    connection,
    idx_name="IDX_DOCS_HYB2",
    vector_store=vs,          # 与 vectorizer_preference 互斥
    params={"parallel": 8},
)
```

说明和提示：

* search\_mode 决定使用哪些信号：
  * "keyword"：仅关键词
  * "semantic"：仅向量
  * "hybrid"（默认）：两者结合
* 通过检索器的 params 参数传递 `DBMS_HYBRID_VECTOR` 参数。
* `return_scores=True` 将总体分数以及组成部分 text\_score 和 vector\_score 添加到 Document.metadata。
* 通过 `acreate_hybrid_index` 和 `OracleHybridSearchRetriever.ainvoke` 支持异步使用。

更多信息：

* [了解混合搜索](https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/understand-hybrid-search.html)
* [`CREATE_PREFERENCE`](https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/create_preference.html)
* [`CREATE_HYBRID_VECTOR_INDEX`](https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/create-hybrid-vector-index.html)
* [`DBMS_HYBRID_VECTOR.SEARCH`](https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/search.html)

### 全文搜索 (Oracle Text)

您可以使用 Oracle Text 直接对 Oracle 数据库运行高质量的关键词搜索。`langchain-oracledb` 集成公开了：

* `create_text_index` / `acreate_text_index`：在列上创建一个 Oracle Text `SEARCH INDEX`。
* `OracleTextSearchRetriever`：运行 `CONTAINS` 查询并返回 LangChain `Document` 对象。

索引选项：

* 如果您有一个 `OracleVS` 向量存储，您可以索引其内置的 "text" 列。
* 您也可以通过直接提供 `table_name` + `column_name` 来索引任何其他表/列。

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain_oracledb.retrievers.text_search import create_text_index, OracleTextSearchRetriever

# 使用 OracleVS 表（索引 'text' 列）
retriever_text = None
create_text_index(
    connection,
    idx_name="IDX_DOCS_TEXT",
    vector_store=vs,
)

# 构建检索器。使用 OracleVS 时，returned_columns 默认为 ["metadata"]。
retriever_text = OracleTextSearchRetriever(
    vector_store=vs,
    k=5,
    fuzzy=True,          # 当 operator_search=False 时，对每个令牌应用 Oracle Text FUZZY
    return_scores=True,  # 将 SCORE(1) 作为 metadata["score"] 添加
)
docs = retriever_text.invoke("退款政策")
for d in docs:
    print(d.page_content, d.metadata.get("score"))

# 或者，索引任意表/列：
# create_text_index(connection, idx_name="IDX_MYDOCS_TEXT", table_name="MYDOCS", column_name="CONTENT")
# retriever_text = OracleTextSearchRetriever(client=connection, table_name="MYDOCS", column_name="CONTENT", k=5)
```

运算符模式和高级查询：

* 默认行为 (`operator_search=False`)：
  * 输入被视为字面文本，在非单词字符上分词，并重写为 ACCUM 表达式。
  * 当 `fuzzy=True` 时，每个令牌被包装为 `FUZZY("token")` 以匹配拼写错误。
* 运算符模式 (`operator_search=True`)：
  * 原样传递 Oracle Text 表达式（`NEAR`、`ABOUT`、`AND`、`OR`、`NOT`、`WITHIN` 等）。在此模式下，fuzzy 被忽略。

返回的列：

* 当针对原始表时，通过 `returned_columns` 在结果中包含额外的列；它们被附加到 `Document.metadata`。
* 使用 `OracleVS` 时，`returned_columns` 默认为 \["metadata"]。

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
# 运算符模式示例
retriever_text_ops = OracleTextSearchRetriever(
    vector_store=vs,
    operator_search=True,   # 直接传递 Oracle Text 表达式
    return_scores=True,
)
docs = retriever_text_ops.invoke('NEAR((policy, refund), 2, TRUE)')
```

说明和提示：

* 当使用 `operator_search=True` 时，fuzzy 被忽略（设计如此）。
* 通过 `acreate_text_index` 和 `OracleTextSearchRetriever.ainvoke` 支持异步使用。

更多信息：

* [Oracle Text `CONTAINS` 查询运算符](https://docs.oracle.com/en/database/oracle/oracle-database/26/ccref/oracle-text-CONTAINS-query-operators.html)
* [模糊匹配和词干提取](https://docs.oracle.com/en/database/oracle/oracle-database/26/ccapp/fuzzy-matching-and-stemming.html)

### 端到端演示

请参阅我们完整的演示指南 [Oracle AI 向量搜索端到端演示指南](https://github.com/langchain-ai/langchain/blob/v0.3/cookbook/oracleai_demo.ipynb)，以借助 Oracle AI 向量搜索构建端到端的 RAG 管道。

***

<div className="source-links">
  <Callout icon="terminal-2">
    [将这些文档](/use-these-docs)通过 MCP 连接到 Claude、VSCode 等，以获取实时答案。
  </Callout>

  <Callout icon="edit">
    [在 GitHub 上编辑此页面](https://github.com/langchain-ai/docs/edit/main/src/oss/python/integrations/vectorstores/oracle.mdx) 或 [提交问题](https://github.com/langchain-ai/docs/issues/new/choose)。
  </Callout>
</div>
