开篇
参考博客《数据导入》将数据库中的数据根据需求导入到solr后,就可以使用这些被导入的数据源进行搜索了。
正文
实例实现顺序从前台开始。页面上有一个搜索框和搜索按钮,输入内容单击搜索按钮请求后台方法开始通过solr实现搜索,按钮调用的js方法。.html为定义的拦截的请求。
function search(a) {
var b = "http://localhost:8082/search.html?q="+
+ encodeURIComponent(document.getElementById(a).value);
return window.location.href = b;
}
以上的请求将会调用Controller中的search方法。
Controller中的search方法实现如下:
public class SearchController {
@Autowired
private SearchService searchService;
@RequestMapping("/search")
public String search(@RequestParam("q")String keyword,
@RequestParam(defaultValue="1")Integer page,
@RequestParam(defaultValue="60")Integer rows, Model model) {
//get乱码处理
try {
keyword = new String(keyword.getBytes("iso8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
keyword = "";
e.printStackTrace();
}
SearchResult searchResult = searchService.search(keyword, page, rows);
//参数传递 给页面
model.addAttribute("query", keyword);
model.addAttribute("totalPages", searchResult.getPageCount());
model.addAttribute("itemList", searchResult.getItemList());
model.addAttribute("page", searchResult.getCurPage());
//返回逻辑视图
return "search";
}
}
调用service返回数据成功后将跳转到search视图。
Service层的实现
@Service
public class SearchServiceImpl implements SearchService {
@Autowired
private SearchDao searchDao;
@Override
public SearchResult search(String keyword, int page, int rows) {
//创建查询条件
SolrQuery query = new SolrQuery();
//设置查询条件
query.setQuery(queryString);
//设置分页条件
query.setStart((page-1)*rows);
query.setRows(rows);
//设置默认搜索域
query.set("df", "item_title");
//设置高亮
query.setHighlight(true);
query.addHighlightField("item_title");
query.setHighlightSimplePre("<font class=\"skcolor_ljg\">");
query.setHighlightSimplePost("</font>");
//执行查询
SearchResult searchResult = searchDao.search(query);
//计算总页数
Long recordCount = searchResult.getRecordCount();
int pageCount = (int) (recordCount / rows);
if (recordCount % rows > 0) {
pageCount++;
}
searchResult.setPageCount(pageCount);
searchResult.setCurPage(page);
return searchResult; }
}
Dao层代码实现
@Repository
public class SearchDaoImpl implements SearchDao {
@Autowired
private SolrServer solrServer;
@Override
public SearchResult search(SolrQuery query) throws Exception {
//执行查询
QueryResponse response = solrServer.query(query);
//取查询结果列表
SolrDocumentList solrDocumentList = response.getResults();
List<SearchItem> itemList = new ArrayList<>();
for (SolrDocument solrDocument : solrDocumentList) {
//创建一个SearchItem对象
SearchItem item = new SearchItem();
item.setCategory_name((String) solrDocument.get("item_category_name"));
item.setId((String) solrDocument.get("id"));
item.setImage((String) solrDocument.get("item_image"));
item.setPrice((Long) solrDocument.get("item_price"));
item.setSell_point((String) solrDocument.get("item_sell_point"));
//取高亮显示
Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
String itemTitle = "";
if (list != null && list.size() > 0) {
//取高亮后的结果
itemTitle = list.get(0);
} else {
itemTitle = (String) solrDocument.get("item_title");
}
item.setTitle(itemTitle);
//添加到列表
itemList.add(item);
}
SearchResult result = new SearchResult();
result.setItemList(itemList);
//查询结果总数量
result.setRecordCount(solrDocumentList.getNumFound());
return result;
}
}
小结
WithOutSolrj:
这种方式是采用http直接访问的方法,所有的搜索条件会拼接成一个URL串,like that:q=title:手机&fl=id,titl,price&start=0&rows=10&sort=price &…&...&…,会采用httpclient向solr发起请求,返回的结果为xml文件,我们需要对结果进行解析。
WithSolrj
面向对象的思想使用setter设置查询条件,最终由solrj拼接url然后向solr服务发起请求。solrj返回的结果是两种方式都是对象类型的,不需要我们解析。一种为solrj自带的SolrDocumentList,另外一种可以我们自定义一个pojo类,使用solrj提供的@Field注解。