Django-dsl-drf Exclude phrase query - django

I am working on integrating Elastic Search in my existing Django REST application. I am using the django-dsl-drf module provided in the link below:
https://django-elasticsearch-dsl-drf.readthedocs.io/
In their documentation 'exclude' query param is provided. But the query only when we provide the full field value.
search-url?exclude=<field-value
For eg: If I have a value 'Stackoverflow' in field 'name'. I'll have to provide query param a
?name__exclude=Stackoverflow to exclude records having 'Stackoverflow' as name in the result. I would like to implement a search in such a way that when I provide 'over', I need to exclude these records, similar to ?name__exclude=over
I checked the above tutorial, but I couldn't find it. Is there any work around so that I can exclude records, fields containing terms instead of providing full field value, which is also case-insensitive.
Thanks a lot.

Using the contains functional filter, you can target documents that have their name field value containing the characters over anywhere in their terms:
?name__contains=over
However, as far as I know, there is no way to negate that filter in django-dsl-drf. You can create an issue requesting that feature, though, because odds are high that you're not the only who needs that, since it's a pretty common way of searching.

Related

Custom index name in South/Django

Is there a way to set our own index name in Django models? Currently, the migration scripts would create a name in format [table_name]_9fcb4ba3 and I'd like to have the name more descriptive, i.e. [table_name]_[column_name] or so.
On the Django's Model Field Reference page, it doesn't seem to have such option (https://docs.djangoproject.com/en/1.8/ref/models/fields/#db-index)
For anyone finding its way from Google - seems Django 1.11 allows you now to have a custom name for indexes. Following the documentation as described here:
Index.name
The name of the index. If name isn’t provided Django will auto-generate a name. For compatibility with different databases, index names cannot be longer than 30 characters and shouldn’t start with a number (0-9) or underscore (_).
There is no way of customizing the name for indexes as these are generated by hashing (the index name calculation uses some hashing techniques)

Hierarchical URLs in Django

Is there a way to implement hierarchical query pattern in Django? As far as I know, the framework only allows to route to views by parsing URLs of a specific format, like:
/customers/{order} -> customer.views.show_orders(order)
But what if I need something like this:
/book1/chapter1/section1/paragraph1/note5 -> notes.view.show(note_id)
where note_id is the id of the last part of the URL, but the URL could have different number of components:
/book1/chapter1
/book1/chapter1/section1
etc.
Each time, it would point to the relevant part of the book depth depending on the depth. Is this doable?
I know there is this: https://github.com/MrKesn/django-mptt-urls, but I am wondering if there is another solution. This isn't ideal for me.
Django URLs are just regular expressions, so the simplest way would be to just ignore everything prior to the "note" section of the URL. For example:
url(r'^.*/note(?P<note_id>[0-9]+)$', 'notes.view.show'),
However, this would ignore the book, chapter, paragraph components. Which would mean your notes would need unique ids across the system, not just within the book. If you needed to capture any number of the interim parts it would be more complicated.
I can't confirm this will work right now, but using non-capture groups in regular expressions, you should be able to capture an optional book and chapter like so:
url(r'^(?:book(?P<book_id>[0-9]+)/)?(?:chapter(?P<chapter_id>[0-9]+)/)?note(?P<note_id>[0-9]+)$', 'notes.view.show'),
Use named groups to accomplish this: https://docs.djangoproject.com/en/dev/topics/http/urls/#named-groups
url(r'^book(?P<book_id>\d+)/chapter(?P<chapter_id>\d+)/section(?P<section_id>\d+)/paragraph(?P<paragraph_id>\d+)/note(?P<note_id>\d+)$', notes.view.show(book_id, chapter_id, section_id, paragraph_id, note_id)
For those who really need a variable-depth URL structure and need the URL to consist strictly of slugs, not IDs, knowing all the components of the URL is critical to retrieve the correct record from the database. Then, the only solution I can think of is using:
url(r'^.*/$', notes.views.show, name='show')
and then parsing the content of the URL to get the individual components after retrieving the URL in the view using the request.path call. This doesn't sound ideal, but it is a way to accomplish it.

Using django-haystack, how do I perform a search with only partial terms?

I've got a Haystack/xapian search index for django.contrib.auth.models.User. The template is simply
{{object.get_full_name}}
as I intend for a user to type in a name and be able to search for it.
My issue is this: if I search, say, Sri (my full first name) I come up with a result for the user object pertaining to my name. However, if I search Sri Ragh - that is, my full name, and part of my last name, I get no results.
How can I set Haystack up so that I can get the appropriate results for partial queries?
(I essentially want it to search *Sri Ragh*, but I don't know if wildcards would actually do the trick, or how to implement them).
This is my search query:
results = SearchQuerySet().filter(content='Sri Ragh')
I use to have a similar problem, as workaround or maybe a Fix you can change the query lookup
results = SearchQuerySet().filter(content__startswith='Sri Ragh')
The issue is that django-haystack doesn't implement all lingos from search engines. Of course you can do this.
results = SearchQuerySet().raw_search('READ THE SEARCH ENGINE QUERY SYNTAX FOR GET WILDCARD LOOKUPS')
As Django-haystack says, this is not portable.
You can use icontains or startswith.
Be careful with this one, if a query is for example 'r', this will bring you all 'Model' entities that have a 'r' in its content.
Model.objects.filter(content__icontains=query)
Model.objects.filter(content__startswith=query)
Look at the documentation

Match all characters in group except for first and last occurrence

Say I request
parent/child/child/page-name
in my browser. I want to extract the parent, children as well as page name. Here are the regular expressions I am currently using. There should be no limit as to how many children there are in the url request. For the time being, the page name will always be at the end and never be omitted.
^([\w-]{1,}){1} -> Match parent (returns 'parent')
(/(?:(?!/).)*[a-z]){1,}/ -> Match children (returns /child/child/)
[\w-]{1,}(?!.*[\w-]{1,}) -> Match page name (returns 'page-name')
The more I play with this, the more I feel how clunky this solution is. This is for a small CMS I am developing in ASP Classic (:(). It is sort of like the MVC routing paths. But instead of calling controllers and functions based on the URL request. I would be travelling down the hierarchy and finding the appropriate page in the database. The database is using the nested set model and is linked by a unique page name for each child.
I have tried using the split function to split with a / delimiter however I found I was nested so many split statements together it became very unreadable.
All said, I need an efficient way to parse out the parent, children as well as page name from a string. Could someone please provide an alternative solution?
To be honest, I'm not even sure if a regular expression is the best solution to my problem.
Thank you.
You could try using:
^([\w-]+)(/.*/)([\w-]+)$
And then access the three matching groups created using Match.SubMatches. See here for more details.
EDIT
Actually, assuming that you know that [\w-] is all that is used in the names of the parts, you can use ^([\w-]+)(.*)([\w-]+)$ instead and it will handle the no-child case fine by itself as well.

Solr Query Syntax

I just got started looking at using Solr as my search web service. I don't know whether Solr supports these query types:
Startswith
Exact Match
Contain
Doesn't Contain
In the range
Could anyone guide me how to implement those features in Solr?
Cheers,
Samnang
Solr is capable of all those things but to adequately explain how to do each of time an answer would become a mini-manual for Solr.
I'd suggest you read the actual manual and tutorials linked from the Solr homepage.
In short though:
Startswith can be implemented using Lucene wildcards.
Exact matches will only be found if a field is not tokanized. I.e. the entire field is viewed as a single token.
Contain is the default search format. I.e. a search for "John" will find any document's whose search field contains the value "John". Prefixing with - (e.g. "-John" will only find documents that do not contain John).
Ranges (be they date or integer) are possible and quite powerful, example date:[* TO NOW] would find any document whose date is not in the future.