
# 相似文档排序召回检索函数和操作符
#### ###
**场景1：**
**功能说明：**基于BM25算法族计算两个文本间的相似度，只对使用BM25索引的查询有效。
- 左参数表示创建BM25索引的索引列名。

- 右参数表示查询文本。
**左参数类型：**text
**右参数类型：**text
**返回值类型：**double precision
**代码示例：**
```
-- 建表及BM25索引
gaussdb=# CREATE TABLE t1(_id TEXT UNIQUE, title TEXT, texts TEXT, metadata TEXT) WITH (storage_type=astore);
gaussdb=# CREATE INDEX "bm25_idx1" ON "t1" USING bm25 ("texts");
-- 执行检索
gaussdb=# SELECT /*+ indexscan(t1 bm25_idx1) */ _id, texts ### 'drop table t1;' AS SCORE FROM t1 ORDER BY SCORE desc LIMIT 10;
```
**场景2：**
**功能说明：**基于BM25算法族计算两个分词文本数组间的相似度，只对使用BM25索引的查询有效。
- 左参数表示创建BM25索引的索引列名。

- 右参数表示查询文本数组。
**左参数类型：**text\[\]
**右参数类型：**text\[\]
**返回值类型：**double precision
**代码示例：**
```
-- 建表及BM25索引
gaussdb=# CREATE TABLE st_information (st_id SERIAL PRIMARY KEY, st_name TEXT[], st_email TEXT[]);
gaussdb=# CREATE INDEX st_information_st_email_bm25_index ON st_information USING bm25(st_email);
-- 执行检索
gaussdb=# SELECT /*+ indexscan(st_information, st_information_st_email_bm25_index) */ st_id, st_email ### '{common-domain@xyz.com}' AS score FROM st_information ORDER BY SCORE desc LIMIT 10;
```
#### gs_ts_dict_add_definition
**功能说明：**增量添加词典内容。
- 第一个参数为词典OID，可以直接输入词典名字符串由数据库内部做自动转换。
- 第二个参数表示该次增量词典内容添加的内容类型，'t'表示关键词或者同义词，'s'表示停用词。
- 第三个参数是添加的词典内容，类型为文本数组，数组中每条数据应单独表示一条词典内容定义。
  ![](https://support.huaweicloud.com/centralized-vector-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  该函数效果等同于DDL语句，运行后会清空所有数据库连接的词典缓存，重新加载词典时会造成BM25文本索引增删查操作大幅度变慢，不建议在线使用。
  
**入参类型：**regdictionary, "char", text\[\]
**出参类型：**BOOLEAN
**代码示例：**
```
gaussdb=# CREATE TEXT SEARCH DICTIONARY test_dict (
    template = tokenweight,
    usedefault = false
);
gaussdb=# call gs_ts_dict_add_definition('test_dict', 't', array['高斯数据库:50']);
-- 对于定义了多关键词的情况，建议使用的导入方式如下：
gaussdb=# do $$
DECLARE
    tempwords TEXT;
begin
    create temp table tokenwords (t text);
    insert into tokenwords values ('单词一'), ('单词二'), ('单词三'), ('单词四'), ('单词五');
    call gs_ts_dict_add_definition('test_dict', 't', (select array_agg(t) into tempwords from tokenwords));
end$$;
gaussdb=# SELECT gs_bm25_tokenize('高斯数据库', 'test_dict');
 gs_bm25_tokenize 
------------------
   {高斯数据库}
(1 row)
```
#### gs_bm25_tokenize
**功能说明：**使用指定词典对输入文本进行分词操作，返回被分割的单词文本数组。
- 第一个入参表示需要分词的文本。
- 第二个入参指定分词使用的词典。
**入参类型：**text, cstring(默认值"pg_catalog.simple_cn_segmentation")
**出参类型：**text\[\]
**代码示例：**
```
gaussdb=# SELECT gs_bm25_tokenize('高斯数据库');
gaussdb=# SELECT gs_bm25_tokenize('高斯数据库', 'pg_catalog.simple_cn_segmentation');
```
#### gs_bm25_inspect
**功能说明：**显示索引磁盘使用和内部词倒排信息等数据。
- 入参表示索引名。
**入参类型：**text
**出参类型** **：**record
**代码示例：**
```
-- 建表及BM25索引
gaussdb=# CREATE TABLE st_information (st_id SERIAL PRIMARY KEY, st_name TEXT[], st_email TEXT[]);
gaussdb=# CREATE INDEX st_information_st_email_bm25_index ON st_information USING bm25(st_email);
-- 执行检索
gaussdb=#  SELECT * FROM gs_bm25_inspect('st_information_st_email_bm25_index');
```
#### gs_bm25_distance_text
**功能说明**：返回bm25文档相似分数，只在使用BM25索引检索时有效。
- 入参一表示创建BM25索引的索引列名。
- 入参二表示查询文本。
**入参类型**：text, text
**出参类型**：double precision
**代码示例**：
```
-- 建表及BM25索引
gaussdb=# CREATE TABLE t1(_id TEXT UNIQUE, title TEXT, texts TEXT, metadata TEXT) WITH (storage_type=astore);
gaussdb=# CREATE INDEX "bm25_idx1" ON "t1" USING bm25 ("texts");
-- 执行检索
gaussdb=# SELECT /*+ indexscan(t1, bm25_idx1) */ _id, gs_bm25_distance_text(texts, 'drop table t1;') AS SCORE FROM t1 ORDER BY texts ### 'drop table t1;' desc LIMIT 10;
```
#### gs_bm25_distance_textarr
**功能说明**：返回bm25文档相似分数，只在使用BM25索引检索时有效。
- 入参一表示创建BM25索引的索引列名。

- 入参二表示查询文本数组。
**入参类型**：text\[\], text\[\]
**出参类型**：double precision
**代码示例** ：
```
-- 建表及BM25索引
gaussdb=# CREATE TABLE st_information (st_id SERIAL PRIMARY KEY, st_name TEXT[], st_email TEXT[]);
gaussdb=# CREATE INDEX st_information_st_email_bm25_index ON st_information USING bm25(st_email);
-- 执行检索
gaussdb=# SELECT /*+ indexscan(st_information, st_information_st_email_bm25_index) */ *, gs_bm25_distance_textarr(st_email, '{common-domain@xyz.com}') AS score FROM st_information ORDER BY st_email ### '{common-domain@xyz.com}' desc LIMIT 10;
```
 #### gs_bm25_docid_info
**功能说明**：返回指定BM25索引中，ctid对应的docid信息。
- 入参一表示BM25索引oid（对于LOCAL分区索引，表示每个分区中索引oid）。

- 入参二表示ctid中的block number。
- 入参三表示ctid中的offset number。
- 出参包含两列数据，第一列列名为dfx_item，表示返回项名称，第二列列名为dfx_info，表示返回项内容，具体说明如[表1]所示：
   表1返回值说明 
  | dfx_item   | dfx_info         |
  |:---|:---|
  | index_name | 索引名。             |
  | doc        | 查询的doc文档。        |
  | ctid       | 查询的ctid。         |
  | docid      | 当前doc文档对应的docid。 |
     
  
![](https://support.huaweicloud.com/centralized-vector-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
不建议在业务期间使用该接口，可能会导致BM25文本索引增删操作效率降低。
**入参类型**：oid, uint4, uint2
**出参类型**：record
**代码示例**：
非分区索引。
```
-- 建表及BM25索引
gaussdb=# SET current_schema=public;
gaussdb=# DROP TABLE IF EXISTS t01;
gaussdb=# CREATE TABLE t01(c1 int, c2 text);
gaussdb=# INSERT INTO t01 VALUES
(1, '向量数据库'),
(2, 'bm25索引'),
(3, 'gsivfflat索引'),
(4, 'gsdiskann索引'),
(5, '向量标量混合索引');
gaussdb=# CREATE INDEX idx ON t01 USING bm25(c2) WITH(num_parallels=16);
-- 查询索引oid，方法1
gaussdb=# SELECT oid FROM pg_class WHERE relname='idx' AND relnamespace=(SELECT oid FROM pg_namespace WHERE nspname='public');
  oid  
-------
 17578
(1 row)
-- 查询索引oid，方法2
gaussdb=# SELECT 'idx'::regclass::oid;
  oid  
-------
 17578
(1 row)
-- 查询元组ctid
gaussdb=# SELECT ctid FROM t01 WHERE c1=2;
 ctid  
-------
 (0,2)
(1 row)
-- 查询ctid对应的docid信息
gaussdb=# SELECT * FROM gs_bm25_docid_info(17578, 0, 2);
  dfx_item  | dfx_info 
------------+----------
 index_name | idx
 doc        | bm25索引
 ctid       | (0,2)
 docid      | 1
(4 rows)
```
LOCAL分区索引，仅查询索引oid方式与上述示例有差异。
```
-- 建分区表及BM25 LOCAL分区索引
gaussdb=# SET current_schema=public;
gaussdb=# DROP TABLE IF EXISTS t01;
gaussdb=# CREATE TABLE IF NOT EXISTS t01(c1 INT, c2 text)
PARTITION BY LIST (c1) AUTOMATIC
(
    PARTITION p1 VALUES(1,2,3,4,5,6,7,8,9,10),
    PARTITION p2 VALUES(11,12,13,14,15,16,17,18,19,20),
    PARTITION p3 VALUES(21,22,23,24,25,26,27,28,29,30)
);
gaussdb=# INSERT INTO t01 VALUES(generate_series(1,30), '向量数据库');
gaussdb=# CREATE INDEX idx ON t01 USING bm25(c2) LOCAL WITH(num_parallels=16);
-- 查询每个分区中索引oid，表t01有三个分区，返回三个oid
gaussdb=# SELECT oid,relname FROM pg_partition WHERE parttype='x' AND parentid='idx'::regclass::oid;
  oid  |  relname  
-------+-----------
 17608 | p3_c2_idx
 17607 | p2_c2_idx
 17606 | p1_c2_idx
(3 rows)
-- 查询p1分区元组ctid
gaussdb=# SELECT ctid FROM t01 WHERE c1=2;
 ctid  
-------
 (0,2)
(1 row)
-- 查询ctid对应的docid信息
gaussdb=# SELECT * FROM gs_bm25_docid_info(17606, 0, 2);
  dfx_item  |  dfx_info  
------------+------------
 index_name | p1_c2_idx
 doc        | 向量数据库
 ctid       | (0,2)
 docid      | 1
(4 rows)
```
#### gs_bm25_document_info
**功能说明**：返回指定BM25索引中，docid对应的正排信息。
- 入参一表示BM25索引oid（对于LOCAL分区索引，表示每个分区中索引oid）。

- 入参二表示docid。
- 出参包含两列数据，第一列列名为dfx_item，表示返回项名称，第二列列名为dfx_info，表示返回项内容，具体说明如[表2]所示：
   表2返回值说明 
  | dfx_item                | dfx_info            |
  |:---|:---|
  | index_name              | 索引名。                |
  | ctid                    | docid对应的ctid。       |
  | doc_index_info_is_alive | 当前docid对应索引信息是否存在。  |
  | token_count_in_index    | 当前文档在索引中包含的token数量。 |
     
  
![](https://support.huaweicloud.com/centralized-vector-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
不建议在业务期间使用该接口，可能会导致BM25文本索引增删操作效率降低。
**入参类型**：oid, uint4
**出参类型**：record
**代码示例**：
非分区索引（分区索引oid查询方式请参见[gs_bm25_docid_info]函数示例）。
```
-- 建表及BM25索引
gaussdb=# SET current_schema=public;
gaussdb=# DROP TABLE IF EXISTS t01;
gaussdb=# CREATE TABLE t01(c1 int, c2 text);
gaussdb=# INSERT INTO t01 VALUES
(1, '向量数据库'),
(2, 'bm25索引'),
(3, 'gsivfflat索引'),
(4, 'gsdiskann索引'),
(5, '向量标量混合索引');
gaussdb=# CREATE INDEX idx ON t01 USING bm25(c2) WITH(num_parallels=16);
-- 查询docid为0的文档正排信息
gaussdb=# SELECT * FROM gs_bm25_document_info('idx'::regclass::oid, 0);
        dfx_item         | dfx_info 
-------------------------+----------
 index_name              | idx
 docid                   | 0
 ctid                    | (0,1)
 doc_index_info_is_alive | true
 token_count_in_index    | 2
(5 rows)
```
#### gs_bm25_tokenhash_info
**功能说明**：返回指定BM25索引的哈希容器信息。
- 入参表示BM25索引oid（对于LOCAL分区索引，表示每个分区中索引oid）。
- 出参包含两列数据，第一列列名为dfx_item，表示返回项名称，第二列列名为dfx_info，表示返回项内容，具体说明如[表3]所示：
   表3返回值说明 
  | dfx_item                | dfx_info               |
  |:---|:---|
  | index_name              | 索引名。                   |
  | hash_bucket_size        | 哈希容器bucket大小。          |
  | total_token_count       | 索引中总单词数。               |
  | bucket_count_in_use     | 使用中的bucket数量。          |
  | empty_bucket_count      | 空的bucket数量。            |
  | hash_bucket_load_factor | 哈希容器负载因子。              |
  | conflict_bucket_count   | 冲突的bucket数量。           |
  | conflict_bucket_ratio   | 冲突的bucket比例。           |
  | bucket_length           | bucket中链表的平均、中位数、最大长度。 |
     
  
![](https://support.huaweicloud.com/centralized-vector-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
不建议在业务期间使用该接口，可能会导致BM25文本索引增删操作效率降低。
**入参类型**：oid
**出参类型**：record
**代码示例**：
非分区索引（分区索引oid查询方式请参见[gs_bm25_docid_info]函数示例）。
```
-- 建表及BM25索引
gaussdb=# SET current_schema=public;
gaussdb=# DROP TABLE IF EXISTS t01;
gaussdb=# CREATE TABLE t01(c1 int, c2 text);
gaussdb=# INSERT INTO t01 VALUES
(1, '向量数据库'),
(2, 'bm25索引'),
(3, 'gsivfflat索引'),
(4, 'gsdiskann索引'),
(5, '向量标量混合索引');
gaussdb=# CREATE INDEX idx ON t01 USING bm25(c2) WITH(num_parallels=16);
-- 查询指定BM25索引的哈希容器信息
gaussdb=# SELECT * FROM gs_bm25_tokenhash_info('idx'::regclass::oid);
        dfx_item         |                             dfx_info                             
-------------------------+------------------------------------------------------------------
 index_name              | idx
 hash_bucket_size        | 10000000
 total_token_count       | 8
 bucket_count_in_use     | 8
 empty_bucket_count      | 9999992
 hash_bucket_load_factor | 0.000080%
 conflict_bucket_count   | 0
 conflict_bucket_ratio   | 0.000000%
 bucket_length           | (avg, med, max) length of the list in a bucket: (0.000001, 1, 1)
(9 rows)
```
#### gs_bm25_token_info
**功能说明**：返回指定BM25索引的token信息。
- 入参一表示BM25索引oid（对于LOCAL分区索引，表示每个分区中索引oid）。

- 入参二表示要查询的文档字符串。
- 出参包含两列数据，第一列列名为token_name，表示文档在索引中包含的token字符串，第二列列名为token_id，表示token的id，返回行数不定。
![](https://support.huaweicloud.com/centralized-vector-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
不建议在业务期间使用该接口，可能会导致BM25文本索引增删操作效率降低。
**入参类型**：oid, text
**出参类型**：record
**代码示例**：
非分区索引（分区索引oid查询方式请参见[gs_bm25_docid_info]函数示例）。
```
-- 建表及BM25索引
gaussdb=# SET current_schema=public;
gaussdb=# DROP TABLE IF EXISTS t01;
gaussdb=# CREATE TABLE t01(c1 int, c2 text);
gaussdb=# INSERT INTO t01 VALUES
(1, '向量数据库'),
(2, 'bm25索引'),
(3, 'gsivfflat索引'),
(4, 'gsdiskann索引'),
(5, '向量标量混合索引');
gaussdb=# CREATE INDEX idx ON t01 USING bm25(c2) WITH(num_parallels=16);
-- 查询文档"向量数据库"在索引中的token信息
gaussdb=# SELECT * FROM gs_bm25_token_info('idx'::regclass::oid, '向量数据库');
 token_name | token_id 
------------+----------
 向量       | 0
 数据库     | 1
(2 rows)
```
#### gs_bm25_posting_info
**功能说明**：返回指定BM25索引中，tokenid对应的倒排信息。
- 入参一表示BM25索引oid（对于LOCAL分区索引，表示每个分区中索引oid）。

- 入参二表示tokenid。
- 出参包含两列数据，第一列列名为dfx_item，表示返回项名称，第二列列名为dfx_info，表示返回项内容，具体说明如[表4]所示：
   表4返回值说明 
  | dfx_item                        | dfx_info                                        |
  |:---|:---|
  | index_name                      | 索引名。                                            |
  | tokenid                         | 查询的tokenid。                                     |
  | inverted_info_total_size        | 倒排信息中包含的总文档数。                                   |
  | uncompressed_inverted_info_size | 倒排信息中未压缩的文档数。                                   |
  | uncompressed_inverted_info      | 倒排表\<docid, appearance（词频）, doc_len（文档中的单词数）\>。 |
  | compressed_inverted_info_size   | 倒排信息中压缩的文档数。                                    |
  | compressed_inverted_info        | 倒排表\<docid, appearance, doc_len\>。              |
  | ...                             | 剩余压缩块中的倒排信息。                                    |
     
  
![](https://support.huaweicloud.com/centralized-vector-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
不建议在业务期间使用该接口，可能会导致BM25文本索引增删操作效率降低。
**入参类型**：oid, text
**出参类型**：record
**代码示例**：
非分区索引（分区索引oid查询方式请参见[gs_bm25_docid_info]函数示例）
```
-- 建表及BM25索引
gaussdb=# SET current_schema=public;
gaussdb=# DROP TABLE IF EXISTS t01;
gaussdb=# CREATE TABLE t01(c1 int, c2 text);
gaussdb=# INSERT INTO t01 VALUES
(1, '向量数据库'),
(2, 'bm25索引'),
(3, 'gsivfflat索引'),
(4, 'gsdiskann索引'),
(5, '向量标量混合索引');
gaussdb=# CREATE INDEX idx ON t01 USING bm25(c2) WITH(num_parallels=16);
-- 查询tokenid为0的单词在索引中的倒排信息
gaussdb=# SELECT * FROM gs_bm25_posting_info('idx'::regclass::oid, 0);
            dfx_item             |       dfx_info       
---------------------------------+----------------------
 index_name                      | idx
 tokenid                         | 0
 inverted_info_total_size        | 2
 uncompressed_inverted_info_size | 2
 uncompressed_inverted_info      | <0, 1, 2> <4, 1, 4> 
 compressed_inverted_info_size   | 0
 compressed_inverted_info        | NA
(7 rows)
```
