Beyond basic search: SearchHeadline returns a snippet with matches wrapped in markers; weighting a SearchVector (A > B > C > D) influences SearchRank; TrigramDistance is 1 − similarity (order ascending for closest); and TrigramWordSimilarity matches a wor
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | # ====================================================================== # Beyond basic search: `SearchHeadline` returns a snippet with matches wrapped # in markers; weighting a `SearchVector` (A > B > C > D) influences # `SearchRank`; `TrigramDistance` is `1 − similarity` (order ascending for # closest); and `TrigramWordSimilarity` matches a word *inside* a longer string. # ====================================================================== # ---------------------------------------------------------------------- # SearchHeadline wraps matches in [ ] # ---------------------------------------------------------------------- # Django: query = SearchQuery("rings", search_type="websearch") Book.objects.annotate( headline=SearchHeadline("title", query, start_sel="[", stop_sel="]") ).values_list("title", "headline") # SQL: # SELECT "examples_book"."title" AS "title", ts_headline("examples_book"."title", websearch_to_tsquery('rings'), 'StartSel=''['', StopSel='']''') AS "headline" # FROM "examples_book" # Result: # Harry Potter: Harry Potter # The Hobbit: The Hobbit # The Lord of the Rings: The Lord of the [Rings] # Postgres for Authors: Postgres for Authors # ---------------------------------------------------------------------- # weighted SearchVector (A) + SearchRank # ---------------------------------------------------------------------- # Django: vector = SearchVector("title", weight="A") query = SearchQuery("postgres") Book.objects.annotate(rank=SearchRank(vector, query)) \ .filter(rank__gt=0).order_by("-rank").values_list("title", "rank") # SQL: # SELECT "examples_book"."title" AS "title", ts_rank(setweight(to_tsvector(COALESCE("examples_book"."title", '')), 'A'), plainto_tsquery('postgres')) AS "rank" # FROM "examples_book" # WHERE ts_rank(setweight(to_tsvector(COALESCE("examples_book"."title", '')), 'A'), plainto_tsquery('postgres')) > 0.0 # ORDER BY 2 DESC # Result: # Postgres for Authors: 0.6079 # ---------------------------------------------------------------------- # TrigramDistance (ascending = closest match) # ---------------------------------------------------------------------- # Django: Book.objects.annotate(dist=TrigramDistance("title", "potter")) \ .order_by("dist").values_list("title", "dist")[:3] # SQL: # SELECT "examples_book"."title" AS "title", ("examples_book"."title" <-> 'potter') AS "dist" # FROM "examples_book" # ORDER BY 2 ASC # LIMIT 3 # Result: # Harry Potter: 0.462 # Postgres for Authors: 0.923 # The Hobbit: 1.000 # ---------------------------------------------------------------------- # TrigramWordSimilarity ('lord' as a word inside the title) # ---------------------------------------------------------------------- # Django: Book.objects.annotate(sim=TrigramWordSimilarity("lord", "title")) \ .order_by("-sim").values_list("title", "sim")[:3] # SQL: # SELECT "examples_book"."title" AS "title", WORD_SIMILARITY('lord', "examples_book"."title") AS "sim" # FROM "examples_book" # ORDER BY 2 DESC # LIMIT 3 # Result: # The Lord of the Rings: 1.000 # Harry Potter: 0.000 # The Hobbit: 0.000 # ---------------------------------------------------------------------- # TrigramWordDistance + Strict word similarity/distance # ---------------------------------------------------------------------- # Django: Book.objects.annotate( wd=TrigramWordDistance("lord", "title"), ss=TrigramStrictWordSimilarity("lord", "title"), sd2=TrigramStrictWordDistance("lord", "title"), ).order_by("wd").values_list("title", "wd", "ss", "sd2")[:3] # SQL: # SELECT "examples_book"."title" AS "title", ('lord' <<-> "examples_book"."title") AS "wd", STRICT_WORD_SIMILARITY('lord', "examples_book"."title") AS "ss", ('lord' <<<-> "examples_book"."title") AS "sd2" # FROM "examples_book" # ORDER BY 2 ASC # LIMIT 3 # Result: # The Lord of the Rings: word_dist=0.000 strict_sim=1.000 strict_dist=0.000 # Harry Potter: word_dist=1.000 strict_sim=0.000 strict_dist=1.000 # The Hobbit: word_dist=1.000 strict_sim=0.000 strict_dist=1.000 |