Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add full-text search to Collection filterset
With this the user can submit their full-text querystring as the 'q' parameter. The results are rank sorted. It provides a weighted result with the following weights: - Namespace name (weight A) - Collection name (weight A) - Collection tags (weight B) - Collection content names (weight C) - Collection description (weight D) https://pulp.plan.io/issues/5075 closes #5075
- Loading branch information
Brian Bouterse
committed
Aug 6, 2019
1 parent
b69488b
commit 32f00b0
Showing
5 changed files
with
134 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Fulltext Collection search is available with the ``q`` filter argument. A migration creates | ||
databases indexes to speed up the search. |
95 changes: 95 additions & 0 deletions
95
pulp_ansible/app/migrations/0004_add_fulltext_search_indexes.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
from django.contrib.postgres import search as psql_search | ||
from django.db import migrations | ||
|
||
|
||
# This query generates full text search index based | ||
# the following data ranked from A to D: | ||
# - Namespace name (weight A) | ||
# - Collection name (weight A) | ||
# - Collection tags (weight B) | ||
# - Collection content names (weight C) | ||
# - Collection description (weight D) | ||
TS_VECTOR_SELECT = ''' | ||
setweight(to_tsvector(coalesce(namespace,'')), 'A') | ||
|| setweight(to_tsvector(coalesce(name, '')), 'A') | ||
|| ( | ||
SELECT | ||
setweight(to_tsvector( | ||
coalesce(string_agg("ansible_tag"."name", ' '), '') | ||
), 'B') | ||
FROM | ||
"ansible_tag" INNER JOIN "ansible_collectionversion_tags" ON ("ansible_tag"."_id" = "ansible_collectionversion_tags"."tag_id") | ||
) | ||
|| ( | ||
SELECT | ||
setweight(to_tsvector( | ||
coalesce(string_agg(cvc ->> 'name', ' '), '') | ||
), 'C') | ||
FROM jsonb_array_elements(cv.contents) AS cvc | ||
) | ||
|| setweight(to_tsvector(coalesce(description, '')), 'D') | ||
''' | ||
|
||
# Generates search vector for existing CollectionVersion objects in the database. | ||
POPULATE_COLLECTIONS_TS_VECTOR = f''' | ||
UPDATE ansible_collectionversion AS c | ||
SET search_vector = ( | ||
SELECT {TS_VECTOR_SELECT} | ||
FROM ansible_collectionversion cv | ||
) | ||
''' | ||
|
||
|
||
# Creates a database function and a trigger to update collection search | ||
# vector field when a collection reference to a newer version is updated. | ||
# | ||
# Since it's not possible to insert a collection version before a collection, a latest_version_id | ||
# always gets updated as a separated query after collectionversion is inserted. Thus only `ON | ||
# UPDATE` trigger is required. | ||
CREATE_COLLECTIONS_TS_VECTOR_TRIGGER = f''' | ||
CREATE OR REPLACE FUNCTION update_collection_ts_vector() | ||
RETURNS TRIGGER AS | ||
$$ | ||
BEGIN | ||
NEW.search_vector := ( | ||
SELECT {TS_VECTOR_SELECT} | ||
FROM ansible_collectionversion cv | ||
WHERE cv.content_ptr_id = NEW.content_ptr_id | ||
); | ||
RETURN NEW; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
CREATE TRIGGER update_ts_vector | ||
BEFORE UPDATE | ||
ON ansible_collectionversion | ||
FOR EACH ROW | ||
EXECUTE PROCEDURE update_collection_ts_vector(); | ||
''' | ||
|
||
DROP_COLLECTIONS_TS_VECTOR_TRIGGER = ''' | ||
DROP TRIGGER IF EXISTS update_ts_vector ON ansible_collectionversion; | ||
DROP FUNCTION IF EXISTS update_collection_ts_vector(); | ||
''' | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('ansible', '0003_add_tags_and_collectionversion_fields'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='collectionversion', | ||
name='search_vector', | ||
field=psql_search.SearchVectorField(default=''), | ||
), | ||
migrations.RunSQL( | ||
sql=POPULATE_COLLECTIONS_TS_VECTOR, | ||
reverse_sql=migrations.RunSQL.noop, | ||
), | ||
migrations.RunSQL( | ||
sql=CREATE_COLLECTIONS_TS_VECTOR_TRIGGER, | ||
reverse_sql=DROP_COLLECTIONS_TS_VECTOR_TRIGGER, | ||
) | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters