Feat/metadata search with postgres fts - #310
Conversation
…ils.OperationalError
|
@alexbainter can you check this out when you have some time |
alexbainter
left a comment
There was a problem hiding this comment.
This is great! Had one comment about a test that looks like it might be missing a couple assertions, but not a big deal. Looking forward to using this for #293!
|
|
||
|
|
||
| class PublicSchemaManager(models.Manager): | ||
| class SchemaQuerySet(models.QuerySet): |
There was a problem hiding this comment.
Oh nice! I introduced a SchemaQuerySet on my branch for #293 too.
| @pytest.mark.django_db | ||
| def test_blank_query_returns_all_without_ranking(): | ||
| SchemaFactory(name="One") | ||
| SchemaFactory(name="Two") | ||
| # Blank / None must not filter or reorder — plain browsing is preserved. | ||
| assert Schema.public_objects.search("").count() == 2 | ||
| assert Schema.public_objects.search(None).count() == 2 |
There was a problem hiding this comment.
The test title and comment seem to imply this should also verify the order of the results. Did you mean to do that too?
There was a problem hiding this comment.
Yes, I completely agree with you. I modified the test in order to check the plain browsing order in which they should get returned.
Thanks for checking that out.
|
I updated the test as you suggested and I agreed with it. This update should mirror what happens in our stg/prod in which the index view builds its base queryset with Thanks for noticing it. I'll move forward and merge this. |
This PR adds Metadata search with Postgres FTS.
Closes #295
The new
searchmethod rank schemas by full-text relevance againstquery_text, withnameweighted abovedescription. Whenquery_textis blank the queryset is returned unchanged, so the caller's existing ordering (e.g. alphabetical on the index page) is preserved for plain browsing.GeneratedFieldis a database-computed column. Postgres itself calculates the value from the expression. It makes no use of triggers, no manual.update(), no overridingsave(). The database keeps it in sync automatically whenever name or description changes.expressionis the full-text search document. In this case just concatenates twoSearchVectors,namewithweight='A'anddescriptionwithweight=B. So a match in the name ranks higher than a match in the description.config="english"appliies English stemming/stop-words rules.output_field=SearchVectorField()tells Django the generated column's type is atsvector.db_persist=Truemeans the value is stored on disk (Postgres STORED generated column), not recomputed on every read. This is required for Postgres, and it’s what lets the GIN index work.