SearchVector/SearchQuery/SearchRank are PostgreSQL full-text search; websearch parses Google-style queries (OR, quotes, -).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | # ====================================================================== # `SearchVector`/`SearchQuery`/`SearchRank` are PostgreSQL full-text search; # `websearch` parses Google-style queries (`OR`, quotes, `-`). # `TrigramSimilarity` (pg_trgm) is typo-tolerant fuzzy matching, and # `__unaccent` strips diacritics so 'muller' finds 'Müller'. # ====================================================================== # ---------------------------------------------------------------------- # websearch 'lord OR postgres' ranked # ---------------------------------------------------------------------- # Django: query = SearchQuery("lord OR postgres", search_type="websearch") Book.objects.annotate(rank=SearchRank("search", query)) \ .filter(search=query).order_by("-rank") \ .values_list("title", "rank") # SQL: # SELECT "examples_book"."title" AS "title", ts_rank(to_tsvector(COALESCE(("examples_book"."search")::text, '')), websearch_to_tsquery('lord OR postgres')) AS "rank" # FROM "examples_book" # WHERE "examples_book"."search" @@ (websearch_to_tsquery('lord OR postgres')) # ORDER BY 2 DESC # Result: # The Lord of the Rings: 0.0304 # Postgres for Authors: 0.0304 # ---------------------------------------------------------------------- # trigram similarity to 'potter' # ---------------------------------------------------------------------- # Django: Book.objects.annotate(sim=TrigramSimilarity("title", "potter")) \ .filter(sim__gt=0.2).order_by("-sim") \ .values_list("title", "sim") # SQL: # SELECT "examples_book"."title" AS "title", SIMILARITY("examples_book"."title", 'potter') AS "sim" # FROM "examples_book" # WHERE SIMILARITY("examples_book"."title", 'potter') > 0.2 # ORDER BY 2 DESC # Result: # Harry Potter: 0.538 # ---------------------------------------------------------------------- # __unaccent: 'muller' matches 'Müller' # ---------------------------------------------------------------------- # Django: Author.objects.filter(name__unaccent__icontains="muller") # SQL: # SELECT "examples_author"."id", "examples_author"."name", "examples_author"."bio", "examples_author"."born", "examples_author"."rating", "examples_author"."nickname" # FROM "examples_author" # WHERE UPPER(UNACCENT("examples_author"."name")::text) LIKE '%' || UPPER(REPLACE(REPLACE(REPLACE((UNACCENT('muller')), E'\\', E'\\\\'), E'%', E'\\%'), E'_', E'\\_')) || '%' # Result: # Karl Müller |