首页 > 解决方案 > 带有分面搜索的 Django 弹性搜索 DSL

问题描述

我在我的 Django 应用程序中使用 ElasticSearch-DSL 来搜索产品。我能够获取结果并将它们放入我的模板(search.html)中,并且它按预期工作。

我做了一些研究,但无法弄清楚如何将分面搜索添加到我的模板以及如何实现分面搜索。

我的文档.py

from django_elasticsearch_dsl import Document
from django_elasticsearch_dsl.registries import registry
from products.models import Products
from elasticsearch_dsl import FacetedSearch, TermsFacet, DateHistogramFacet


@registry.register_document
class CarDocument(Document):
    class Index:
        # Name of the Elasticsearch index
        name = 'cars'
        # See Elasticsearch Indices API reference for available settings
        settings = {'number_of_shards': 1,
                    'number_of_replicas': 1}



    class Django:
        model = Products # The model associated with this Document

        # The fields of the model you want to be indexed in Elasticsearch
        fields = [
            'body_id',
            'product_make',
            'model_name',
            'product_id',
            'model_id', 
            'variant',
            'transmission',
            'bodystyle',
            'yom',
            'status',
            'ex_showroom',
            'registration_fees',
            'insurance',
            'handling_charges',
            'fastag',
            'on_road_price',
            'min_price',
            'max_price',
            'rating',

        ]

        # Ignore auto updating of Elasticsearch when a model is saved
        # or deleted:
        # ignore_signals = True

        # Don't perform an index refresh after every update (overrides global setting):
        # auto_refresh = False

        # Paginate the django queryset used to populate the index with the specified size
        # (by default it uses the database driver's default setting)
        # queryset_pagination = 5000

我的views.py代码如下:

from django.shortcuts import render
from elasticsearch_dsl import Q
from elasticsearch_dsl.query import MultiMatch
# Create your views here.
from search.documents import CarDocument
from products.models import Products
from django.core.paginator import (
    Paginator, Page, EmptyPage, PageNotAnInteger
)
from django.utils.functional import LazyObject

def search(request):
   q = request.GET.get('q')
   if q:
       #cars = CarDocument.search().query("match", model_name=q)
      q = request.GET.get('q', None)
      query1 = MultiMatch(query=q,  fields=['product_make', 'bodystyle','model_name','variant','transmission','yom'],fuzziness='AUTO')

      s = CarDocument.search().query(query1)
      total = s.count()
      s= s[0:total]
      cars = s.execute()

      paginator = Paginator(cars, 100)
      page = request.GET.get('page')
      cars = paginator.get_page(page)
   else:
      cars = ''


   return render(request, 'search/search.html', {'cars': cars})

def product_detail(request,*args, **kwargs):

    return render(request, 'product_details.html', {})

我的网址.py

urlpatterns = [
    url(r'^$', home_view, name='home'),
    url(r'^home/', home_view, name='home'),
    url(r'^search/', search, name='search'),
    url(r'^select/', select, name='select'),
    url('ajax/home_view/',home_view, name='ajax_load_models'),
    url(r'^carmodels/(?P<product_make>\w+)/(?P<model_name>\w+)/$', product_detail, name='product_detail'),
    ]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

我的问题是我应该进行哪些更改以及在哪里使用 product_make、body_style、max-min 价格范围等的多面搜索。

标签: djangoelasticsearch-dslelasticsearch-dsl-py

解决方案


此页面上有一个示例方面:

class BlogSearch(FacetedSearch):
    index = 'blogs'
    doc_types = [Blog, Post]
    fields = ['title', 'category', 'description', 'body']

    facets = {
        'type': TermsFacet(field='_type'),
        'category': TermsFacet(field='category'),
        'weekly_posts': DateHistogramFacet(field='published_from',interval='week')
    }

    def search(self):
        ' Override search to add your own filters '
        s = super(BlogSearch, self).search()
        return s.filter('term', published=True)

# when using:
blog_search = BlogSearch("web framework", filters={"category": "python"})

# supports pagination
blog_search[10:20]

response = blog_search.execute()

# easy access to aggregation results:
for category, hit_count, is_selected in response.facets.category:
print(
    "Category %s has %d hits%s." % (
        category,
        hit_count,
        ' and is chosen' if is_selected else ''
    )
)

上述代码的版权归链接文档页面的贡献者所有,并根据Apache License 2.0获得许可。


推荐阅读