django haystack 2.0 contains query - django

Even though doc says
The contains filter became the new default filter as of Haystack v2.X (the default in Haystack v1.X was exact). This changed because exact caused problems and was unintuitive for new people trying to use Haystack. contains is a much more natural usage. http://django-haystack.readthedocs.org/en/latest/searchqueryset_api.html
I find my Solr returns exact match.
I tried subclassing SearchForm and overriding search function to use
filter(content__contains=...) as suggested by django haystack how do I find substrings in words?
But it doesn't work.
How do I do the contains search?
Using Ngram suggested in Django-Haystack with Solr contains search is the only way to do it?
I'm using solr 3.6 if that matters.

Related

Querying Django Postgres for Fuzzy FTS + Typeahead

I'm using PostgreSQL 12.3 with Django 3.0.8. I'm trying to implement a typeahead functionality. I tried using Trigram similarity, but that didn't work too well since, if I were to have a text saying "chair," I would have to type "cha" before I get results.
I'm using corejavascript/twitter's typeahead JS library. Their first example (The Basics) allows you to type in a single letter and get results instantly, some of which are not even the prefix of the word.
How would I do that? You can view my current functionality here: https://github.com/Donate-Anything/Donate-Anything/blob/76348e9362d386d3d6375b9a75d47d5765960992/donate_anything/item/views.py#L21-L30
I thought that I should use to_tsvector with a SearchVectorField, but when I implemented that (with a query like this:
queryset = (
Item.objects.defer("is_appropriate")
.filter(name_search=str(query))
)
then I don't even see the results until I type in the full word. What would my implementation look like then? (Article for implementing the triggers for SearchVectorField)

haystack query for solr to find items where attribute is unset or specified value

I'm trying to query solr through haystack for all objects that either does not have an attribute (it's Null) or the attribute is a specified value.
I can query solr directly with the snippet (brand:foo OR (*:* -brand:*)) and get what I want. But I can't find a way to formulate this or anything logically the same through haystack without really ugly hacks.
I did find this ugly hack:
SearchQuerySet().filter(brand=Raw('%s OR (*:* -brand:*)' % Clean('foo'))
But it chains really poorly with that OR in there without any parenthesis around it.
Ideally a solution using a pure filter would be best, but failing that a way to add a chainable filter using raw solr query language.
I'm using django-haystack 2.4.0
It's not a perfect match, but narrow helps me enough to let me do what I want
SearchQuerySet().narrow('(brand:%s OR (*:* -brand:*))' % Clean('foo'))

Accent insensitive search django sqlite

I am using sqlite and django. I am trying to search for accented strings stored in the sqlite database using non-accented search query.
For example: search for "Rio Grande" when the database contains "Río Grande".
I found this SO post SQLite accent-insensitive search that mentions to first create a collation and then call the search query using COLLATE NOACCENTS
This is exactly what I need. However I am not sure how to do this using django models. Any suggestions?
As suggested in this Postgres specific post on django documentation: PostgreSQL specific lookups I tried the following:
myObject.objects.filter(locationTuple__unaccent__contains='Rio Grande')
but got the following error:
FieldError: Unsupported lookup 'unaccent' for CharField or join on the field not permitted. which is understandable because this lookup might not work for sqlite.
I think this is the closest thing you're going to find, however, it needs some development work:
https://github.com/djcoin/django-unaccent
I'm jealous as well, as my workplace isn't on PostgreSQL either (yet).

Django Haystack similarity search

I'm a Django newbie doing a primitive website. I installed haystack and Whoosh as its search engine cause it was the simplest thing to do. It works fine, but there is a problem and I don't know how to Google it. I have some categories on my site and I have indexed their names to search. So, when a user enters "Computing" it finds the computing category and links to it. But there is a problem. If a user enters "Comp" into search field, it doesn't find "Computing" at all. Is this something that can be configured and how?
EDIT:
What else have I tried? Installing haystack 2.0, following this tutorial, installing solr instead of whoosh, trying Ngram fields, rebuilding indexes 10 times, rewriting search_indexes.py. Everything. Doesn't work. If I type in Comp, it doesn't find Computing. Is there anything else I could do? I have noticed that in the tutorial above, everything works like a charm instantly.
When you do the usual:
SearchQuerySet().filter(title='Computing')
in Haystack 1.x, it filters on everything exactly matching 'Computing'.
You can change that behaviour by using Haystack's Field Lookups, for example, using 'contains' will filter on anything containing the given string (Computing, Utingcomp, Comp):
SearchQuerySet().filter(title__contains='Comp')
In Haystack 2.x, the default filter is 'contains', so it should behave as you would expect it to "out-of-the-box"
Check out the documentation on autocomplete. You need to setup your indices to support Ngram's, but this should be exactly what you need.
from haystack.query import SearchQuerySet
SearchQuerySet().autocomplete(content_auto='old')
# Result match things like 'goldfish', 'cuckold' & 'older'.
So, if I'm understanding, what you're looking for is the equivalent of 'LIKE' in SQL.
The problem is search engines that back Haystack aren't like an RDBMS.
The low level implementation of this filter will involve using wildcard characters but most of the Haystack backends don't support a leading wildcard, something required for an icontains/endswith filter. However, since most backends support trailing wildcards, Haystack 2.x includes a startswith filter. The only case this doesn't handle is searching for the end of a word, which doesn't look to be possible.
So, if you have indexed:
"Look at our great discounts in Computer section"
Then the following Haystack query DO match:
SearchQuerySet().filter(title__startswith='comp')
# match!
Notice the difference between Django vs. Haystack startswith filters. Django startswith will match at the beginning of the complete sentence (i.e. a CharField), but the Haystack one will match at the beginning of a token (i.e. each word in a complete sentence).
Hope it helps!

How do you access/configure summaries/snippets in Django Haystack

I'm working on getting django-haystack set up on my site, and am trying to have snippets in my search results roughly like so:
Title of result one about Wikis ...this special thing about wiki values is that...I always use a wiki when I walk...snippet value three talks about wikis too...and here's another snippet value
about wikis.
I know there's a template tag that uses Haystack code to do the the highlighting, but the snippets it generates are pretty limited:
they always start with the query word
there's only one snippet value
they don't support asterisk queries
and other stuff?
Is there a way to use the Solr backend to generate proper snippets as shown above?
Bottom line is that the Solr highlighting can't really be used by Haystack in a flexible way. I spoke to the main developer for Haystack on IRC, and he said basically, if I want to have the kind of highlighting I'm looking for, the only way to get it is to extend the Solr backend that Haystack uses.
I dabbled in that for about half a day, but couldn't get Haystack to recognize my custom back end. Haystack has some magic backend loading code that just wasn't working with me.
Consequently, I've switched over to sunburnt, which provides a lighter-weight and more extensible wrapper around Solr. I'm hoping it will fare better.
from haystack.utils import Highlighter
my_text = 'This is a sample block that would be more meaningful in real life.'
my_query = 'block meaningful'
highlight = Highlighter(my_query)
highlight.highlight(my_text)
http://docs.haystacksearch.org/dev/highlighting.html