我的网站上有一个用elasticsearch实现的搜索功能。 现在我对设计有一点疑问。
我有searchAction
路由/search
,它在查询字符串中包含一个参数。与/search?terms=...
一样。
我想将结果列表过滤掉,但我对正确的设计有一些疑问。
制作过滤结果列表的最佳解决方案是什么?
如果我传递filter参数,我需要使用当前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参数和后置过滤器的表单中,我需要在搜索操作中使用这两种类型的参数。这好吗?
相反,链接现在会在$get
请求中包含所有参数,但我不喜欢在模板中使用查询字符串构建网址。
最好的方法是什么?
答案 0 :(得分:2)
将KNP paginator捆绑包与搜索操作一起使用。在搜索表单上对post中的searchAction进行post操作,并在使用匹配条件对数据进行排序后,重新呈现页面。
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;
}
答案 1 :(得分:0)
我更喜欢查询字符串中的所有参数,这些参数允许用户为网址添加书签或通过电子邮件发送。
答案 2 :(得分:0)
这取决于。
1如果您不需要索引(例如搜索引擎优化 - 谷歌机器人)过滤结果页面,在我看来,您应该使用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()
));
}