2

我的网站上有一个使用 elasticsearch 实现的搜索功能。现在我有一个关于设计的小问题。

我有一个searchAction带有查询字符串中的参数的路由/search。喜欢/search?terms=...

我想让结果列表可过滤,但我对实现这一目标的正确设计有些怀疑。

列出过滤结果的最佳解决方案是什么?

如果我传递过滤器参数,我需要使用当前 url 指定一个表单操作,并像链接一样附加当前查询字符串,对吗?例子:

<form action="{{ current_pat }} ~ {{ query_string }}" method="post">
    <input type="checkbox" name="filter_one">....

在这种情况下,网址会喜欢:/search?terms=...并且$post我有过滤器。这是正确的解决方案,还是链接列表更好?例子:

<ul>
    <li><a href="{{current_path}} ~ {{ query_string }} ~ {{ this_filter }}">... 
    <li><a href="{{current_path}} ~ {{ query_string }} ~ {{ this_another_filter }}">
...

在这种情况下,网址将类似于:/search?terms=...&this_filter=...

在带有 get 参数和 post 过滤器的表单情况下,我需要在搜索操作中同时采用这两种类型的参数。这个好吗?

相反,链接现在将在$get请求中包含所有参数,但我不喜欢在模板中使用查询字符串构建 url。

最好的方法是什么?

4

3 回答 3

2

将 KNP 分页器包与搜索操作一起使用。在搜索表单上,对 Controller 中的 searchAction 进行发布操作,并在使用匹配条件对数据进行排序后,重新渲染页面。

public function searchAction(Request $request,array $arguments = array())
        {
            $em = $this->getDoctrine()->getManager();
            $paginator = $this->get('knp_paginator');
            $parameter = $request->get('board_search');
            $boardRepo = $this->getDoctrine()->getRepository('PNCMISDashboardBundle:ExaminationBoards')->loadBoardByName($parameter);
            $boards = $paginator->paginate($boardRepo, $this->get('request')->query->get('page', 1), 10);
            return $this->render('PNCMISDashboardBundle:ExaminationBoards/CRUD:index.html.twig', array(
                    'boards'=> $boards,
                )
            );
        }


public function loadBoardByName($name)
    {
        $q = $this
            ->createQueryBuilder('boards')
            ->where('upper(boards.name) LIKE upper(:search)')
            ->setParameter('search', '%'.$name.'%')
            ->getQuery()
        ;
        try {
            // The Query::getSingleResult() method throws an exception
            // if there is no record matching the criteria.
            $user = $q->getResult();
        } catch (NoResultException $e) {
            throw new UsernameNotFoundException(sprintf('Unable to find an board identified by "%s".', $name), null, 0, $e);
        }
        return $user;
    }
于 2015-11-20T14:25:28.303 回答
0

我更喜欢在查询字符串中包含所有参数,这将允许用户为网址添加书签或通过电子邮件发送。

于 2013-02-15T15:32:19.530 回答
0

这取决于。

1 如果您不需要索引(例如 SEO - google bot)过滤的结果页面,我认为您应该使用 AJAX 来实现这一点。

路由:

search_result:
    pattern: /search
    defaults:  { _controller: AcmeExampleBundle:Ajax:searchResult }
    requirements:
        _method:  POST

JavaScript(伪代码)

filterResults() {
    var queryString = $('input#toSearch').val();
    var filters = new Object();
    filters['someKey'] = someVal;
    $.post('/search', {filters: filters, queryString: queryString}, function(data) {
        $('#resultList').html(data);
    });)
}

当然,您不应该对 url '/search' 进行硬编码。

控制器:

// src/Acme/ExampleBundle/Controller/AjaxController.php
    // ...
    public function searchResultAction()
    {
        $filters = $this->getRequest()->get('filters', array());
        $searchObject = new searchObj(); 
        // or smt like $this->get('service_name'); if you use search object as service
        // you can also use entity manager
        $searchObject->setQueryString($this->getRequest()->get('queryString'));
        $searchObject->setFilters($filters);
        return $this->render('AcmeExampleBundle:Ajax:searchResult.html.twig', array(
            'records' => $searchObject->getResults()
        ));
    }

当然你可以返回 json 响应,但在我看来,返回准备注入模板的一部分是最容易管理的

并查看:

{% for record in records %}
    <div class="record">{{ record.title }}</div>
{% endfor %}

2 如果你想索引过滤的结果页面,你应该使用用户友好的 URL,而不是 AJAX 方法

路由:

search_result:
    pattern: /search/{queryString}/{make}/{model}
    defaults:  { _controller: AcmeExampleBundle:Ajax:searchResult }
    requirements:
        _method:  GET

控制器:

// src/Acme/ExampleBundle/Controller/AjaxController.php
    // ...
    public function searchResultAction($queryString, $make, $model)
    {
        $filters = array('make' => $make, 'model' => $model);
        $searchObject = new searchObj(); 
        // or smt like $this->get('service_name'); if you use search object as service
        // you can also use entity manager
        $searchObject->setQueryString($queryString);
        $searchObject->setFilters($filters);
        return $this->render('AcmeExampleBundle:Ajax:searchResult.html.twig', array(
            'records' => $searchObject->getResults()
        ));
    }
于 2013-02-16T00:50:19.203 回答