9

I'm using Django Full Text search to search across multiple fields but have an issue when searching using partial strings.

Lets say we have a report object with the name 'Sample Report'.

vector = SearchVector('name') + SearchVector('author__username')

search = SearchQuery('Sa')

Report.objects.exclude(visible=False).annotate(search=vector).filter(search=search)

The following QuerySet is empty but if I include the full word 'Sample' then the report will appear in the QuerySet.

Is there anyway to use icontains or prefixing with django full text search?

Bryden Fogelman
  • 103
  • 1
  • 2
  • 5
  • Possible duplicate of https://stackoverflow.com/questions/45110067/django-full-text-search-wildcard – Scornwell Aug 04 '17 at 23:15
  • I agree this does look like a duplicate to me, I'm curious if this PR was merged it'd be possible to only use Django ORM https://code.djangoproject.com/ticket/27899 – Bryden Fogelman Aug 04 '17 at 23:18

2 Answers2

6

This is working on Django 1.11:

tools = Tool.objects.annotate(
    search=SearchVector('name', 'description', 'expert__user__username'),
).filter(search__icontains=form.cleaned_data['query_string'])

Note the icontains in the filter.

santiagopim
  • 556
  • 5
  • 13
  • 13
    I am getting a database error `ERROR: function replace(tsquery, unknown, unknown) does not exist at character 1603` `HINT: No function matches the given name and argument types. You might need to add explicit type casts.` When I attempt to use a `SearchQuery` for the search query. – Matt Feb 24 '20 at 19:51
0

@santiagopim solution is correct but to address Matt's comment for if you get the following error:

ERROR:  function replace(tsquery, unknown, unknown) does not exist 
at character 1603 HINT:  No function matches the given name 
and argument types. You might need to add explicit type casts.

You have to remove the call to SearchQuery and just use a plain string.

I know this doesn't address the underlying issue for if you need to use SearchQuery but if you are like me and just need a quick fix, you can try the following.


vector = SearchVector('name') + SearchVector('author__username')

# NOTE: I commented out the line below
# search = SearchQuery('Sa')
search = 'Sa'

Report.objects.exclude(visible=False).annotate(search=vector)\
.filter(search__icontains =search)

This other answer might be helpful.

Tomiwa
  • 840
  • 12
  • 14