跳到内容

集合版本如何进行关键词搜索。

当导入一个集合时,会在 ansible_collectionversion 表中创建一个包含关于工件元数据的行。

导入后,pulp_ansible 运行一个函数来确定相关集合版本的最高语义版本。然后使用 is_hight=True|False 更新相关行。

该行更新会触发一个 postgres 函数运行,该函数“标记化”集合元数据中的各种字符串,例如命名空间、名称、标签和描述。这些标记根据其来源进行加权,并且权重会影响搜索特定字符串时的最终得分 ...

https://postgresql.ac.cn/docs/current/textsearch-controls.html

https://github.com/pulp/pulp_ansible/blob/main/pulp_ansible/app/migrations/0046_add_fulltext_search_fix.py

galaxy_ng=# select namespace,name,version,search_vector from ansible_collectionversion where namespace='zabbix';
 namespace |  name  | version |                                                             search_vector                                                             
-----------+--------+---------+---------------------------------------------------------------------------------------------------------------------------------------
 zabbix    | zabbix | 1.0.4   | 'agent':6B,10C,13 'agent2':8B 'agentd':7B 'deploy':11 'host':16 'linux':3B 'manag':15 'monitor':4B 'scale':18 'zabbix':1A,2A,5B,9C,12
(1 row)

当 API 基于关键字减少集合列表时,后端使用过滤器集在 postgres 中调用 “ts_rank” 函数 ...

https://github.com/pulp/pulp_ansible/blob/93e330dca8accfa438a615b6be2194c169655e7c/pulp_ansible/app/galaxy/v3/filters.py#L152-L161

有了这些信息,我们可以直接查询数据库来模拟 API 的行为。

这是一个搜索 "zabbix" 的示例 ...

galaxy_ng=# SELECT namespace,name,version
FROM ansible_collectionversion
WHERE search_vector @@ to_tsquery('english', 'zabbix')
ORDER BY ts_rank(search_vector, to_tsquery('english', 'zabbix')) DESC;

 namespace |  name  | version 
-----------+--------+---------
 zabbix    | zabbix | 1.0.4
(1 row)

这是一个搜索 "zab" 的示例 ..

galaxy_ng=# SELECT namespace,name,version
FROM ansible_collectionversion
WHERE search_vector @@ to_tsquery('english', 'zab')
ORDER BY ts_rank(search_vector, to_tsquery('english', 'zab')) DESC;
 namespace | name | version 
-----------+------+---------
(0 rows)

请注意,"zab" 没有结果。这是因为 zabbix 的 search_vector 字段中缺少匹配的标记。这意味着我们的搜索向量不是部分字符串匹配或打字完成工具。所有搜索查询都必须是与标记化单词之一完全匹配的字符串(或该字符串的标记化版本)。