app search (bug 673578)
This commit is contained in:
Родитель
49c468fec4
Коммит
7cd54189fc
|
@ -243,6 +243,13 @@ SORT_CHOICES = (
|
|||
('updated', _lazy(u'Last Update')),
|
||||
)
|
||||
|
||||
APP_SORT_CHOICES = (
|
||||
(None, _lazy(u'Relevance')),
|
||||
('downloads', _lazy(u'Most Downloads')),
|
||||
('rating', _lazy(u'Highest Rating')),
|
||||
('updated', _lazy(u'Last Update')),
|
||||
)
|
||||
|
||||
|
||||
class ESSearchForm(forms.Form):
|
||||
q = forms.CharField(required=False)
|
||||
|
@ -255,6 +262,12 @@ class ESSearchForm(forms.Form):
|
|||
cat = forms.CharField(required=False)
|
||||
sort = forms.ChoiceField(required=False, choices=SORT_CHOICES)
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
addon_type = kw.pop('type', None)
|
||||
super(ESSearchForm, self).__init__(*args, **kw)
|
||||
if addon_type == amo.ADDON_WEBAPP:
|
||||
self.fields['sort'].choices = APP_SORT_CHOICES
|
||||
|
||||
def clean_sort(self):
|
||||
sort = self.cleaned_data.get('sort')
|
||||
return sort if sort in dict(SORT_CHOICES) else None
|
||||
|
|
|
@ -37,8 +37,12 @@
|
|||
<h2>{{ _('Refine Results') }}</h2>
|
||||
{{ facet_links(_('Sort by'), sorting) }}
|
||||
{{ facet_links(_('Category'), categories) }}
|
||||
{{ facet_links(_('{app} Version')|f(app=APP.pretty), versions) }}
|
||||
{{ facet_links(_('Platform'), platforms) }}
|
||||
{% if versions %}
|
||||
{{ facet_links(_('{app} Version')|f(app=APP.pretty), versions) }}
|
||||
{% endif %}
|
||||
{% if platforms %}
|
||||
{{ facet_links(_('Platform'), platforms) }}
|
||||
{% endif %}
|
||||
{{ facet_links(_('Tagged'), tags) }}
|
||||
</section>
|
||||
|
||||
|
|
|
@ -15,10 +15,12 @@ from amo.decorators import json_view
|
|||
from amo.helpers import urlparams
|
||||
from amo.utils import MenuItem, sorted_groupby
|
||||
from versions.compare import dict_from_int, version_int
|
||||
from search import forms
|
||||
from search.client import (Client as SearchClient, SearchError,
|
||||
from webapps.models import Webapp
|
||||
|
||||
from . import forms
|
||||
from .client import (Client as SearchClient, SearchError,
|
||||
CollectionsClient, PersonasClient, sphinx)
|
||||
from search.forms import SearchForm, SecondarySearchForm, ESSearchForm
|
||||
from .forms import SearchForm, SecondarySearchForm, ESSearchForm
|
||||
|
||||
DEFAULT_NUM_RESULTS = 20
|
||||
|
||||
|
@ -267,6 +269,53 @@ def ajax_search(request):
|
|||
return []
|
||||
|
||||
|
||||
def name_query(q):
|
||||
# 1. Prefer text matches first (boost=3).
|
||||
# 2. Then try fuzzy matches ("fire bug" => firebug) (boost=2).
|
||||
# 3. Then look for the query as a prefix of a name (boost=1.5).
|
||||
# 4. Look for text matches inside the summary (boost=0.8).
|
||||
# 5. Look for text matches inside the description (boost=0.3).
|
||||
return dict(name__text={'query': q, 'boost': 3},
|
||||
name__fuzzy={'value': q, 'boost': 2, 'prefix_length': 4},
|
||||
name__startswith={'value': q, 'boost': 1.5},
|
||||
summary__text={'query': q, 'boost': 0.8},
|
||||
description__text={'query': q, 'boost': 0.3})
|
||||
|
||||
|
||||
@mobile_template('search/es_results.html')
|
||||
def app_search(request, template=None):
|
||||
form = ESSearchForm(request.GET or {}, type=amo.ADDON_WEBAPP)
|
||||
form.is_valid() # Let the form try to clean data.
|
||||
query = form.cleaned_data
|
||||
qs = (Webapp.search().query(or_=name_query(query['q']))
|
||||
.filter(type=amo.ADDON_WEBAPP, status=amo.STATUS_PUBLIC,
|
||||
is_disabled=False)
|
||||
.facet(tags={'terms': {'field': 'tag'}},
|
||||
categories={'terms': {'field': 'category', 'size': 100}}))
|
||||
if query.get('tag'):
|
||||
qs = qs.filter(tag=query['tag'])
|
||||
if query.get('cat'):
|
||||
qs = qs.filter(category=query['cat'])
|
||||
if query.get('sort'):
|
||||
mapping = {'downloads': '-weekly_downloads',
|
||||
'rating': '-bayesian_rating',
|
||||
'updated': '-last_updated'}
|
||||
qs = qs.order_by(mapping[query['sort']])
|
||||
|
||||
pager = amo.utils.paginate(request, qs)
|
||||
facets = pager.object_list.facets
|
||||
|
||||
ctx = {
|
||||
'pager': pager,
|
||||
'query': query,
|
||||
'form': form,
|
||||
'sorting': sort_sidebar(request, query, form),
|
||||
'categories': category_sidebar(request, query, facets),
|
||||
'tags': tag_sidebar(request, query, facets),
|
||||
}
|
||||
return jingo.render(request, template, ctx)
|
||||
|
||||
|
||||
# pid => platform
|
||||
# lver => appver
|
||||
# sort options
|
||||
|
@ -288,18 +337,7 @@ def es_search(request, tag_name=None, template=None):
|
|||
|
||||
query = form.cleaned_data
|
||||
|
||||
# 1. Prefer text matches first (boost=3).
|
||||
# 2. Then try fuzzy matches ("fire bug" => firebug) (boost=2).
|
||||
# 3. Then look for the query as a prefix of a name (boost=1.5).
|
||||
# 4. Look for text matches inside the summary (boost=0.8).
|
||||
# 5. Look for text matches inside the description (boost=0.3).
|
||||
q = query['q']
|
||||
search = dict(name__text={'query': q, 'boost': 3},
|
||||
name__fuzzy={'value': q, 'boost': 2, 'prefix_length': 4},
|
||||
name__startswith={'value': q, 'boost': 1.5},
|
||||
summary__text={'query': q, 'boost': 0.8},
|
||||
description__text={'query': q, 'boost': 0.3})
|
||||
qs = (Addon.search().query(or_=search)
|
||||
qs = (Addon.search().query(or_=name_query(query['q']))
|
||||
.filter(status__in=amo.REVIEWED_STATUSES, is_disabled=False,
|
||||
app=APP.id)
|
||||
.facet(tags={'terms': {'field': 'tag'}},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import amo
|
||||
from amo.urlresolvers import reverse
|
||||
from addons.models import Addon
|
||||
from versions.models import Version
|
||||
|
||||
|
@ -23,6 +24,9 @@ class Webapp(Addon):
|
|||
# Set the slug once we have an id to keep things in order.
|
||||
self.update(slug='app-%s' % self.id, _current_version=version)
|
||||
|
||||
def get_url_path(self, impala=None):
|
||||
return reverse('apps.detail', args=[self.app_slug])
|
||||
|
||||
|
||||
# These are the translated strings we want to pull in.
|
||||
translated = 'name', 'summary', 'description'
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from django.conf.urls.defaults import include, url
|
||||
from django.conf.urls.defaults import url
|
||||
|
||||
from . import views
|
||||
|
||||
|
||||
urlpatterns = (
|
||||
url(r'(?P<app_slug>[^/<>"\']+)/$', views.app_detail, name='apps.detail'),
|
||||
url(r'^search/$', 'search.views.app_search', name='apps.search'),
|
||||
url(r'^(?P<app_slug>[^/<>"\']+)/$', views.app_detail, name='apps.detail'),
|
||||
)
|
||||
|
|
Загрузка…
Ссылка в новой задаче