This quickstart shows you how to build a Retrieval-Augmented Generation (RAG) application by using the OpenAPI of AnalyticDB for PostgreSQL. You use a Python development environment to prepare the vector database, manage documents, retrieve content, and integrate retrieval with LangChain.
Architecture
The RAG architecture uses an information retrieval system to extend the capabilities of a large language model (LLM) with relevant context, such as industry-specific or private documents. The following figure shows the RAG architecture.

This getting-started guide is based on FastANN, the in-house vector engine of AnalyticDB for PostgreSQL. The OpenAPI encapsulates the following AI Service capabilities:
Multi-tenant management
Document processing: load, split, embedding, and multi-modal processing
Retrieval: vector search, full-text search, and reranking
Prerequisites
An Alibaba Cloud account. If you do not have one, register for an account on the Alibaba Cloud official website.
If you use AnalyticDB for PostgreSQL for the first time, you must authorize a service-linked role in the console:
Log on to the AnalyticDB for PostgreSQL console.
In the upper-right corner of the page, click Create Instance.
In the Create Service Linked Role dialog box, click OK.
Your Alibaba Cloud account or RAM user must have the permissions to manage AnalyticDB for PostgreSQL (
AliyunGPDBFullAccess).An AnalyticDB for PostgreSQL instance. For instructions, see Create an instance.
Step 1: Create an initial account
AnalyticDB for PostgreSQL provides two types of users:
Privileged user — The initial account has the
RDS_SUPERUSERrole with full database permissions.Standard user — No default permissions. A privileged user or a user with the
To create the initial account, perform the following steps:GRANTpermission must grant access to database objects. For more information, see Create and manage users.
Log on to the AnalyticDB for PostgreSQL console and go to the details page of your instance.
In the left-side navigation pane, click Account Management.
Click Create Account.
In the Create Account window, enter an account name and set a password, and then click OK.
The following table describes the parameters.
| Parameter | Description |
| Account | The initial account name. The name must contain only lowercase letters, digits, and underscores (_), start with a lowercase letter, end with a lowercase letter or digit, and be 2 to 16 characters long. It cannot start with gp. |
| New Password and Confirm Password | The password must be 8 to 32 characters long and contain characters from at least three of the following categories: uppercase letters, lowercase letters, digits, and special characters. The supported special characters are Note For data security, change your password regularly and do not reuse previous passwords. |
Step 2: Prepare the development environment
Check the Python environment
This tutorial uses the Python 3 SDK. Run the following commands to check that Python 3.9 or later and pip are installed:
python3 -V
pip --versionIf Python is not installed or the version is earlier than 3.9, install Python.
Install the SDK
Install the alibabacloud_gpdb20160503 and alibabacloud_tea_openapi SDKs. The sample code uses them for authentication and client creation.
pip install --upgrade alibabacloud_gpdb20160503 alibabacloud_tea_openapiConfigure environment variables
Store sensitive information such as credentials and the instance ID in environment variables to prevent leaks caused by hardcoding.
Linux&macOS
Run
vim ~/.bashrcto open the~/.bashrcfile. On macOS, runvim ~/.bash_profile.Add the following content to the configuration file. On the RAM user list page, click the username to get the AccessKey ID and AccessKey secret of the RAM user. In the AnalyticDB for PostgreSQL console, view the instance ID and the region ID.
# Replace access_key_id with the AccessKey ID of the RAM user export ALIBABA_CLOUD_ACCESS_KEY_ID="access_key_id" # Replace access_key_secret with the AccessKey secret of the RAM user export ALIBABA_CLOUD_ACCESS_KEY_SECRET="access_key_secret" # Replace instance_id with the ID of the AnalyticDB for PostgreSQL instance, for example, gp-bp166cyrtr4p***** export ADBPG_INSTANCE_ID="instance_id" # Replace instance_region with the ID of the region where the AnalyticDB for PostgreSQL instance resides, for example, cn-hangzhou export ADBPG_INSTANCE_REGION="instance_region"In the vim editor, press Esc, enter
:wqto save the file, and then exit the editor.Run
source ~/.bashrcto apply the configuration file. On macOS, runsource ~/.bash_profile.
Windows
To set the environment variables temporarily for the current session, run the following commands in CMD:
REM Replace access_key_id with the AccessKey ID of the RAM user
set ALIBABA_CLOUD_ACCESS_KEY_ID=access_key_id
REM Replace access_key_secret with the AccessKey secret of the RAM user
set ALIBABA_CLOUD_ACCESS_KEY_SECRET=access_key_secret
REM Replace instance_id with the ID of the AnalyticDB for PostgreSQL instance, for example, gp-bp166cyrtr4p*****
set ADBPG_INSTANCE_ID=instance_id
REM Replace instance_region with the ID of the region where the AnalyticDB for PostgreSQL instance resides, for example, cn-hangzhou
set ADBPG_INSTANCE_REGION=instance_regionStep 3: Prepare the database environment
Preparation process
Build a client that you use for operations such as creating a vector database.
Initialize the vector database. All vector data is stored in the fixed database named
knowledgebase, so you must run the initialization once for each instance. Initializing the vector database does the following:Creates the
knowledgebasedatabase and grants read and write permissions on it.Creates the Chinese tokenizer and full-text search features. These features work at the database level.
Create a namespace, which you use to create document collections.
Create a document collection (DocumentCollection) to store chunk text and vector data.
Sample code
Before you run the code, replace account and account_password with your actual database account and password. Modify the other settings as needed.
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_gpdb20160503.client import Client
from alibabacloud_gpdb20160503 import models as gpdb_20160503_models
import os
# --- Get the credentials and instance information from the environment variables ---
ALIBABA_CLOUD_ACCESS_KEY_ID = os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID']
ALIBABA_CLOUD_ACCESS_KEY_SECRET = os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']
ADBPG_INSTANCE_ID = os.environ['ADBPG_INSTANCE_ID']
ADBPG_INSTANCE_REGION = os.environ['ADBPG_INSTANCE_REGION']
# Build and return an API client for AnalyticDB for PostgreSQL
def get_client():
config = open_api_models.Config(
access_key_id=ALIBABA_CLOUD_ACCESS_KEY_ID,
access_key_secret=ALIBABA_CLOUD_ACCESS_KEY_SECRET
)
config.region_id = ADBPG_INSTANCE_REGION
# https://api.alibabacloud.com/product/gpdb
if ADBPG_INSTANCE_REGION in ("cn-beijing", "cn-hangzhou", "cn-shanghai", "cn-shenzhen", "cn-hongkong",
"ap-southeast-1"):
config.endpoint = "gpdb.aliyuncs.com"
else:
config.endpoint = f'gpdb.{ADBPG_INSTANCE_REGION}.aliyuncs.com'
return Client(config)
# Initialize the vector database
def init_vector_database(account, account_password):
request = gpdb_20160503_models.InitVectorDatabaseRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
manager_account=account,
manager_account_password=account_password
)
response = get_client().init_vector_database(request)
print(f"init_vector_database response code: {response.status_code}, body:{response.body}")
# Create a namespace
def create_namespace(account, account_password, namespace, namespace_password):
request = gpdb_20160503_models.CreateNamespaceRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
manager_account=account,
manager_account_password=account_password,
namespace=namespace,
namespace_password=namespace_password
)
response = get_client().create_namespace(request)
print(f"create_namespace response code: {response.status_code}, body:{response.body}")
# Create a document collection
def create_document_collection(account,
account_password,
namespace,
collection,
metadata: str = None,
full_text_retrieval_fields: str = None,
parser: str = None,
embedding_model: str = None,
metrics: str = None,
hnsw_m: int = None,
pq_enable: int = None,
external_storage: int = None,):
request = gpdb_20160503_models.CreateDocumentCollectionRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
manager_account=account,
manager_account_password=account_password,
namespace=namespace,
collection=collection,
metadata=metadata,
full_text_retrieval_fields=full_text_retrieval_fields,
parser=parser,
embedding_model=embedding_model,
metrics=metrics,
hnsw_m=hnsw_m,
pq_enable=pq_enable,
external_storage=external_storage
)
response = get_client().create_document_collection(request)
print(f"create_document_collection response code: {response.status_code}, body:{response.body}")
if __name__ == '__main__':
# The initial database account of the AnalyticDB for PostgreSQL instance.
account = "testacc"
# The password of the initial account.
account_password = "Test1234"
# The name of the namespace to create.
namespace = "ns1"
# The password of the namespace. Use this password for subsequent data read and write operations.
namespace_password = "Ns1password"
# The name of the document collection to create.
collection = "dc1"
metadata = '{"title":"text", "page":"int"}'
full_text_retrieval_fields = "title"
embedding_model = "m3e-base"
init_vector_database(account, account_password)
create_namespace(account, account_password, namespace, namespace_password)
create_document_collection(account, account_password, namespace, collection,
metadata=metadata, full_text_retrieval_fields=full_text_retrieval_fields,
embedding_model=embedding_model)Parameters
| Parameter | Description |
account | The initial database account of the AnalyticDB for PostgreSQL instance. |
account_password | The password of the initial account. |
namespace | The name of the namespace to create. |
namespace_password | The password of the namespace. Use this password for subsequent data read and write operations. |
collection | The name of the document collection to create. |
metadata | The metadata of the custom map structure. The key is the field name and the value is the field type. |
full_text_retrieval_fields | The custom comma-separated full-text search fields. Each field must be a key in metadata. |
parser | The tokenizer. Default value: zh_cn. For more information, see CreateDocumentCollection. |
embedding_model | The embedding model. For more information, see CreateDocumentCollection. |
metrics | The index algorithm. For more information, see CreateDocumentCollection. |
hnsw_m | The maximum number of neighbors in the HNSW algorithm. Valid values: 1 to 1000. For more information, see CreateDocumentCollection. |
pq_enable | Specifies whether the index uses Product Quantization (PQ) acceleration. For more information, see CreateDocumentCollection. |
external_storage | Specifies whether to use the mmap cache. For more information, see CreateDocumentCollection. |
View the table schema
After the preceding code runs, log on to the database to view the table schema:
Log on to the AnalyticDB for PostgreSQL console.
In the upper-right corner of the instance details page, click Log On to Database.
On the Logon Instance page, enter the Account and Database Password, and then click Log On.
After you log on, you can see a new database namedknowledgebasein the instance, a schema namedns1in theknowledgebasedatabase, and a table nameddc1in that schema. The following table describes the schema of thedc1table.
| Field | Type | Field source | Description |
id | text | Fixed field | The primary key. The UUID of a single chunk of text. |
vector | real[] | Fixed field | The vector data array. The length matches the dimensions of the specified embedding model. |
doc_name | text | Fixed field | The document name. |
content | text | Fixed field | A single chunk of text, generated after the document passes through the loader and the splitter. |
loader_metadata | json | Fixed field | The metadata generated when the loader parses the document. |
to_tsvector | TSVECTOR | Fixed field | Stores the full-text search data. The data comes from the fields specified by full_text_retrieval_fields. The content field is included by default, so this column supports full-text search on both the content and title data sources. |
title | text | Defined in metadata | Custom field. |
page | int | Defined in metadata | Custom field. |
Step 4: Manage documents
The sample code in this section uses the environment variables and the get_client() function defined in Step 3: Prepare the database environment. Run it in the same script as the code from that section.
Upload a document
The following sample code uploads a local document asynchronously:
import time
import io
from typing import Dict, List, Any
from alibabacloud_tea_util import models as util_models
from alibabacloud_gpdb20160503 import models as gpdb_20160503_models
def upload_document_async(
namespace,
namespace_password,
collection,
file_name,
file_path,
metadata: Dict[str, Any] = None,
chunk_overlap: int = None,
chunk_size: int = None,
document_loader_name: str = None,
text_splitter_name: str = None,
dry_run: bool = None,
zh_title_enhance: bool = None,
separators: List[str] = None):
with open(file_path, 'rb') as f:
file_content_bytes = f.read()
request = gpdb_20160503_models.UploadDocumentAsyncAdvanceRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
file_name=file_name,
metadata=metadata,
chunk_overlap=chunk_overlap,
chunk_size=chunk_size,
document_loader_name=document_loader_name,
file_url_object=io.BytesIO(file_content_bytes),
text_splitter_name=text_splitter_name,
dry_run=dry_run,
zh_title_enhance=zh_title_enhance,
separators=separators,
)
response = get_client().upload_document_async_advance(request, util_models.RuntimeOptions())
print(f"upload_document_async response code: {response.status_code}, body:{response.body}")
return response.body.job_id
def wait_upload_document_job(namespace, namespace_password, collection, job_id):
def job_ready():
request = gpdb_20160503_models.GetUploadDocumentJobRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
job_id=job_id,
)
response = get_client().get_upload_document_job(request)
print(f"get_upload_document_job response code: {response.status_code}, body:{response.body}")
return response.body.job.completed
while True:
if job_ready():
print("successfully load document")
break
time.sleep(2)
if __name__ == '__main__':
job_id = upload_document_async("ns1", "Ns1password", "dc1",
"test.pdf", "/root/test.pdf")
wait_upload_document_job("ns1", "Ns1password", "dc1", job_id)Parameters
| Parameter | Description |
namespace | The name of the namespace where the document collection resides. |
namespace_password | The password of the namespace. |
collection | The name of the document collection to store the document. |
file_name | The document name, including the file name extension. |
file_path | The local path of the document. The maximum file size is 200 MB. |
metadata | The metadata of the document. It must match the metadata specified when you created the document collection. |
chunk_overlap | The splitting policy for large data. The amount of data that overlaps between consecutive chunks. The maximum value cannot exceed chunk_size. |
chunk_size | The splitting policy for large data. The size of each chunk when the data is split into smaller parts. Maximum value: 2048. |
document_loader_name | If you do not specify this parameter, the loader is matched automatically based on the file name extension. For more information about automatic loader matching, see UploadDocumentAsync. |
text_splitter_name | The name of the splitter. For more information about document splitting, see UploadDocumentAsync. |
dry_run | Specifies whether to only parse and split the document without vectorizing and storing it. Valid values: true: only parses and splits the document. false (default): parses and splits the document, and then vectorizes and stores it. |
zh_title_enhance | Specifies whether to enable Chinese title enhancement. Valid values: true, false. |
separators | The delimiters of the splitting policy for large data. You usually do not need to specify this parameter. |
vl_enhance | Specifies whether to enable VL-enhanced content recognition for complex documents. Valid values: true, false. This parameter is available only on the China site. |
splitter_model | When document_loader_name is set to ADBPGLoader and text_splitter_name is set to LLMSplitter, you can use this parameter to specify the splitting model. Default value: qwen3-8b. Supported splitting models: qwq-plus, qwq-plus-latest, qwen-max, qwen-max-latest, qwen-plus, qwen-plus-latest, qwen-turbo, qwen-turbo-latest, qwen3-235b-a22b, qwen3-32b, qwen3-30b-a3b, qwen3-14b, qwen3-8b, qwen3-4b, qwen3-1.7b, qwen3-0.6b, qwq-32b, qwen2.5-14b-instruct-1m, qwen2.5-7b-instruct-1m, qwen2.5-72b-instruct, qwen2.5-32b-instruct, qwen2.5-14b-instruct, qwen2.5-7b-instruct, qwen2.5-3b-instruct, qwen2.5-1.5b-instruct, and qwen2.5-0.5b-instruct. This parameter is available only on the China site. |
(Optional) Other document management operations
List documents
The following sample code lists the documents in a document collection:
def list_documents(namespace, namespace_password, collection):
request = gpdb_20160503_models.ListDocumentsRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
)
response = get_client().list_documents(request)
print(f"list_documents response code: {response.status_code}, body:{response.body}")
if __name__ == '__main__':
list_documents("ns1", "Ns1password", "dc1")Parameters
| Parameter | Description |
namespace | The name of the namespace where the document collection resides. |
namespace_password | The password of the namespace. |
collection | The name of the document collection. |
View document details
The following sample code queries the details of a document:
def describe_document(namespace, namespace_password, collection, file_name):
request = gpdb_20160503_models.DescribeDocumentRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
file_name=file_name
)
response = get_client().describe_document(request)
print(f"describe_document response code: {response.status_code}, body:{response.body}")
if __name__ == '__main__':
describe_document("ns1", "Ns1password", "dc1", "test.pdf")Parameters
| Parameter | Description |
namespace | The name of the namespace where the document collection resides. |
namespace_password | The password of the namespace. |
collection | The name of the document collection. |
file_name | The document name. |
Response parameters
| Parameter | Description |
DocsCount | The number of chunks that the document is split into. |
TextSplitter | The name of the document splitter. |
DocumentLoader | The name of the document loader. |
FileExt | The file name extension of the document. |
FileMd5 | The MD5 hash value of the document. |
FileMtime | The time when the document was last uploaded. |
FileSize | The file size, in bytes. |
FileVersion | The document version, of the INT type. It indicates how many times the document has been uploaded and updated. |
Delete a document
The following sample code deletes a document from a document collection:
def delete_document(namespace, namespace_password, collection, file_name):
request = gpdb_20160503_models.DeleteDocumentRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
file_name=file_name
)
response = get_client().delete_document(request)
print(f"delete_document response code: {response.status_code}, body:{response.body}")
if __name__ == '__main__':
delete_document("ns1", "Ns1password", "dc1", "test.pdf")Parameters
| Parameter | Description |
namespace | The name of the namespace where the document collection resides. |
namespace_password | The password of the namespace. |
collection | The name of the document collection. |
file_name | The document name. |
Step 5: Retrieve documents
The sample code in this section uses the environment variables and the get_client() function defined in Step 3: Prepare the database environment. Run it in the same script as the code from that section.
This section uses plain text retrieval as an example. The following sample code shows how to retrieve documents:
def query_content(namespace, namespace_password, collection, top_k,
content,
filter_str: str = None,
metrics: str = None,
use_full_text_retrieval: bool = None):
request = gpdb_20160503_models.QueryContentRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
content=content,
filter=filter_str,
top_k=top_k,
metrics=metrics,
use_full_text_retrieval=use_full_text_retrieval,
)
response = get_client().query_content(request)
print(f"query_content response code: {response.status_code}, body:{response.body}")
if __name__ == '__main__':
query_content('ns1', 'Ns1password', 'dc1', 10, 'What is ADBPG?')Parameters
| Parameter | Description |
namespace | The name of the namespace where the document collection resides. |
namespace_password | The password of the namespace. |
collection | The name of the document collection. |
top_k | The number of retrieval results with the highest similarity to return. |
content | The text content to retrieve. |
filter_str | The filter statement applied before retrieval. |
metrics | The vector distance algorithm. If you do not specify this parameter, the algorithm specified when the index was created is used. |
use_full_text_retrieval | Specifies whether to use full-text search. Valid values: true (uses full-text search) and false (default, does not use full-text search). |
Response parameters
| Parameter | Description |
Id | The UUID of the chunk generated after splitting. |
FileName | The document name. |
Content | The retrieved content, which is a single chunk generated after splitting. |
LoaderMetadata | The metadata generated when the document was uploaded. |
Metadata | The custom metadata. |
RetrievalSource | The retrieval source. Valid values: 1: hit by vector search. 2: hit by full-text search. 3: hit by both vector search and full-text search. |
Score | The similarity score calculated by the specified similarity algorithm. |
Step 6: Integrate with LangChain
LangChain is an open source framework for building applications on large language models (LLMs). It connects models to external data through a complete set of interfaces and tools. The following example integrates the retrieval capabilities of AnalyticDB for PostgreSQL into LangChain to implement a question-answering system.
The sample code in this section uses the environment variables and the get_client() function defined in Step 3: Prepare the database environment. Run it in the same script as the code from that section.
This example uses an OpenAI model as the large language model. Replace YOUR_OPENAI_API_KEY in the following code with your OpenAI API key.
Install the modules
Run the following command to install the modules:
pip install --upgrade langchain langchain-openai openai tiktokenBuild the AdbpgRetriever
The following class wraps the query_content operation as a LangChain retriever:
from typing import List
from langchain_core.retrievers import BaseRetriever
from langchain_core.callbacks import CallbackManagerForRetrieverRun
from langchain_core.documents import Document
class AdbpgRetriever(BaseRetriever):
namespace: str = None
namespace_password: str = None
collection: str = None
top_k: int = None
use_full_text_retrieval: bool = None
def query_content(self, content) -> List[gpdb_20160503_models.QueryContentResponseBodyMatchesMatchList]:
request = gpdb_20160503_models.QueryContentRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=self.namespace,
namespace_password=self.namespace_password,
collection=self.collection,
content=content,
top_k=self.top_k,
use_full_text_retrieval=self.use_full_text_retrieval,
)
response = get_client().query_content(request)
return response.body.matches.match_list
def _get_relevant_documents(
self, query: str, *, run_manager: CallbackManagerForRetrieverRun
) -> List[Document]:
match_list = self.query_content(query)
return [Document(page_content=i.content) for i in match_list]Create the chain
The following code creates a retrieval-augmented question-answering chain:
import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain.schema import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
OPENAI_API_KEY = "YOUR_OPENAI_API_KEY"
os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI()
def format_docs(docs):
return "\n\n".join([d.page_content for d in docs])
retriever = AdbpgRetriever(namespace='ns1', namespace_password='Ns1password', collection='dc1', top_k=10, use_full_text_retrieval=True)
chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| model
| StrOutputParser()
)Ask a question
Call the chain to ask a question:
chain.invoke("What is AnalyticDB PostgreSQL?")
# Answer:
# AnalyticDB PostgreSQL is a cloud-native online analytical processing (OLAP) service from Alibaba Cloud. It extends the open source PostgreSQL database and provides a high-performance, high-capacity data warehouse solution.
# It combines the flexibility and compatibility of PostgreSQL with the high-concurrency, high-speed query capabilities required for data analytics and reporting.
#
# AnalyticDB PostgreSQL suits large-scale datasets, supports real-time analytics and decision support, and helps enterprises with data mining, business intelligence (BI), reporting, and data visualization.
# As a managed service, it simplifies data warehouse management and O&M, so you can focus on data analytics instead of the underlying infrastructure.
# Main features:
#
# High-performance analytics - Uses columnar storage and a massively parallel processing (MPP) architecture to query and analyze large volumes of data quickly.
# Easy scaling - Scales resources horizontally and vertically based on data volume and query performance requirements.
# PostgreSQL compatibility - Supports the PostgreSQL SQL language and most tools in the PostgreSQL ecosystem, so existing PostgreSQL users can migrate and adapt easily.
# Security and reliability - Provides data backup, restoration, and encryption to keep data secure and reliable.
# Cloud-native integration - Integrates closely with other Alibaba Cloud services, such as data integration and data visualization tools.
# In summary, AnalyticDB PostgreSQL is a high-performance, scalable cloud data warehouse service that lets enterprises run complex data analytics and reporting in the cloud.Appendix
Full-text search
To improve retrieval accuracy, AnalyticDB for PostgreSQL supports full-text search in addition to vector similarity search. You can use both at the same time for dual-path recall.
Define the full-text search fields
Before you use full-text search, specify which fields serve as the data source. The document collection API uses the content field by default. You can also specify other custom metadata fields.
Tokenization
When you create a document collection, you can specify the tokenizer by using the parser parameter. In most scenarios, use the default Chinese tokenizer zh_cn. If you have special tokenization requirements, contact Alibaba Cloud technical support.
When data is inserted, the tokenizer splits the data of the specified full-text search fields by delimiter and stores the result in to_tsvector for subsequent full-text search.
Embedding models
AnalyticDB for PostgreSQL supports the following embedding models:
| embedding_model | Dimensions | Description |
m3e-small | 512 | From moka-ai/m3e-small. Supports Chinese only, not English. |
m3e-base | 768 | From moka-ai/m3e-base. Supports Chinese and English. |
text2vec | 1024 | From GanymedeNil/text2vec-large-chinese. Supports Chinese and English. |
text-embedding-v1 | 1536 | The general-purpose text embedding model from Model Studio. Supports Chinese and English. |
text-embedding-v2 | 1536 | The upgraded version of text-embedding-v1. |
clip-vit-b-32 (multi-modal) | 512 | An open source multi-modal model that supports images. |
Custom embedding models are not supported.
For more supported models, see Embedding models.
Vector index
You can set the following parameters for a vector index:
| Parameter | Description |
metrics | The similarity distance algorithm. Valid values: l2: builds the index by using the squared Euclidean distance function. Suitable for image similarity retrieval. ip: builds the index by using the inverse inner product distance function. Typically used to replace cosine similarity after vectors are normalized. cosine: builds the index by using the cosine distance function. Suitable for text similarity retrieval. |
hnsw_m | The maximum number of neighbors in the HNSW algorithm. OpenAPI sets different values automatically based on the vector dimensions. |
pq_enable | Specifies whether to enable PQ vector dimensionality reduction. Valid values: 0: disabled. 1: enabled. PQ vector dimensionality reduction relies on existing vector samples for training. We do not recommend that you set this parameter if the data volume is less than 500,000 rows. |
external_storage | Specifies whether to build the HNSW index by using mmap. Valid values: 0: builds the index by using segmented page storage by default. This mode can use shared_buffer in PostgreSQL as the cache and supports operations such as delete and update. 1: builds the index by using mmap. This mode does not support operations such as delete and update. |
Document parsing
Select a loader based on the document type:
UnstructuredHTMLLoader:
.htmlUnstructuredMarkdownLoader:
.mdPyMuPDFLoader:
.pdfPyPDFLoader:
.pdfRapidOCRPDFLoader:
.pdfJSONLoader:
.jsonCSVLoader:
.csvRapidOCRLoader:
.png,.jpg,.jpeg, or.bmpUnstructuredFileLoader:
If you do not specify.eml,.msg,.rst,.txt,.xml,.docx,.epub,.odt,.pptx, or.tsvdocument_loader_name, the loader is determined automatically by the file name extension. If a document type has multiple loaders, such as PDF, you can specify any one of them.
Document splitting
The splitting result depends on chunk_overlap, chunk_size, text_splitter_name. The valid values of text_splitter_name are as follows:
ChineseRecursiveTextSplitter: inherits from RecursiveCharacterTextSplitter. By default, it uses
["\n\n","\n", "。|!|?","\.\s|\!\s|\?\s", ";|;\s", ",|,\s"]as delimiters and matches them with regular expressions. It works better than RecursiveCharacterTextSplitter for Chinese.SpacyTextSplitter: uses
["\n\n", "\n", " ", ""]as delimiters by default. It supports splitting code in languages such asc++,go,java,js,php,proto,python,rst,ruby,rust,scala,swift,markdown,latex,html,sol, andcsharp.RecursiveCharacterTextSplitter: uses
\n\nas the default delimiter and the en_core_web_sm model of the Spacy library to split text. It works well for documents written entirely in English.MarkdownHeaderTextSplitter: splits Markdown documents by using
[ ("#", "head1"), ("##", "head2"), ("###", "head3"), ("####", "head4") ].