Re: Implementing a basic search for my website

2017-02-21 Thread Carlo Ascani
Thank you for all the answers!

Given that I am implementing this for a demo purpose, I do not care about 
performances.
I think I am going to do the 2 queries approach for the demo, then I would 
use a FTS engine in the future.

Thanks a lot

Carlo


Il giorno martedì 21 febbraio 2017 02:09:46 UTC+1, Shawn Milochik ha 
scritto:
>
> If you want a pre-rolled solution, just use Django-haystack. It'll do 
> exactly what you want.
>
> If you want to create your own to avoid the dependency on additional 
> libraries and backend (you'll need something like Elasticsearch), that's 
> easy also. Let me know if you do. I have some sample code lying around and 
> will dig it up and document it a bit if you're interested in implementing 
> it. You'll still need to have to store your own indexed data in some kind 
> of backend, but you can use whatever you like.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/c1e0b295-4008-4cc3-8ca9-63bebe2395f5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Implementing a basic search for my website

2017-02-20 Thread Shawn Milochik
If you want a pre-rolled solution, just use Django-haystack. It'll do
exactly what you want.

If you want to create your own to avoid the dependency on additional
libraries and backend (you'll need something like Elasticsearch), that's
easy also. Let me know if you do. I have some sample code lying around and
will dig it up and document it a bit if you're interested in implementing
it. You'll still need to have to store your own indexed data in some kind
of backend, but you can use whatever you like.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CAOzwKwEtpBWGizLfkJ0t_Uy5cZVwnGHL10kG8MhaOji68MMdUg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Implementing a basic search for my website

2017-02-20 Thread Melvyn Sopacua
Hi Carlo,

On Monday 20 February 2017 07:33:08 Carlo Ascani wrote:

> class ASearch(ListView):
> model = A
> template_name = 'search_result.html'
> 
> def get_context_data(self, **kwargs):
> context = super(A, self).get_context_data(**kwargs)
> results = A.objects.all()
> query = self.request.GET.get('q')
> 
> if query:
> query_list = query.split()
> 
> results = results.filter(
> reduce(operator.or_, (
> Q(roles__name__icontains=q)
> for q in query_list)) |
> reduce(operator.or_, (
> Q(location__name__iexact=q)
> for q in query_list))
> )
> 
> context.update({
> 'results': results
> })
> return context

I think in itself your logic is already becoming complex. With the added 
condition, which 
is in essence "scoring the results" a simple ordering can't be done here. It 
really is 
worth looking into Full Text Search options of your database engine or use an 
external 
service for it.

If you feel like doing it this way anyway, I would do the reordering in python 
- 
databases have invented FTS for this for a good reason: reordering a result set 
almost 
always involves doing temporary tables, especially if the ordering conditions 
are not a 
table field, but a condition of the results.

The good thing is that the sorting is in fact a split: if both have a match, 
move to top, 
else move to bottom, so a classic Tail Queue will work.

And that also makes using Ludovic's suggestion viable: use 2 queries. One 
anding the 
2 conditions, which should be fast and the second somewhat more complex: where 
NOT the anded condition and the OR condition.

Which to pick, is really a matter of performance: which method does best under 
pressure and what resource can you scale cheaper / faster?
-- 
Melvyn Sopacua

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/495884511.RQ4aaiMVnE%40devstation.
For more options, visit https://groups.google.com/d/optout.


Re: Implementing a basic search for my website

2017-02-20 Thread ludovic coues
You can split your query set in two. First search elements with both
elements then elements with only one.

Obviously, that's two request, so there might be better way to handle the
problem.

On 20 Feb 2017 4:33 p.m., "Carlo Ascani"  wrote:

> Hi all,
> I am just trying to add a search funcionality to my frontend.
> I know it is a huge topic, so sorry my n00bih questions.
>
> I have a model A
>
> class A(models.Model):
> roles = models.ManyToManyField(B)
> location = models.ForeignKey(C)
> ...
>
>
> These 2 fields are the only fields I care about
> when searching, so I would say I need a very
> specific field based search funcionality.
>
> I wrote this view to handle it
>
>
> class ASearch(ListView):
> model = A
> template_name = 'search_result.html'
>
> def get_context_data(self, **kwargs):
> context = super(A, self).get_context_data(**kwargs)
> results = A.objects.all()
> query = self.request.GET.get('q')
>
> if query:
> query_list = query.split()
>
> results = results.filter(
> reduce(operator.or_, (
> Q(roles__name__icontains=q)
> for q in query_list)) |
> reduce(operator.or_, (
> Q(location__name__iexact=q)
> for q in query_list))
> )
>
> context.update({
> 'results': results
> })
> return context
>
>
>
> This is quite working. I mean, results are fine.
> But the problem is that I would like that searches
> who covers *all* conditions to come first.
>
> For example, let's say I search for 'MyRole MyLocation'
> the results I get are all the As for MyRole and all the
> As for MyLocation, mixed.
>
> I would like that As with MyRole AND MyLocation to show
> up first.
>
>
> I hope I was clear enough, but I doubt it.
>
> Thank you in advance
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users+unsubscr...@googlegroups.com.
> To post to this group, send email to django-users@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit https://groups.google.com/d/
> msgid/django-users/2c34b391-95d3-4ae9-acb1-81649833a725%40googlegroups.com
> 
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CAEuG%2BTb_wx0YLZyx%2B7Ax1v7%2BsczrtZfCPYVFbcicQ2t7PhrK_w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Implementing a basic search for my website

2017-02-20 Thread Carlo Ascani
Hi all,
I am just trying to add a search funcionality to my frontend.
I know it is a huge topic, so sorry my n00bih questions.

I have a model A

class A(models.Model):
roles = models.ManyToManyField(B)
location = models.ForeignKey(C)
...


These 2 fields are the only fields I care about
when searching, so I would say I need a very
specific field based search funcionality.

I wrote this view to handle it


class ASearch(ListView):
model = A
template_name = 'search_result.html'

def get_context_data(self, **kwargs):
context = super(A, self).get_context_data(**kwargs)
results = A.objects.all()
query = self.request.GET.get('q')

if query:
query_list = query.split()

results = results.filter(
reduce(operator.or_, (
Q(roles__name__icontains=q)
for q in query_list)) |
reduce(operator.or_, (
Q(location__name__iexact=q)
for q in query_list))
)

context.update({
'results': results
})
return context



This is quite working. I mean, results are fine.
But the problem is that I would like that searches
who covers *all* conditions to come first.

For example, let's say I search for 'MyRole MyLocation'
the results I get are all the As for MyRole and all the
As for MyLocation, mixed.

I would like that As with MyRole AND MyLocation to show
up first.


I hope I was clear enough, but I doubt it.

Thank you in advance

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/2c34b391-95d3-4ae9-acb1-81649833a725%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.