Spring Data Solr完成按关键字搜索功能

上一节

四、完成按关键字搜索功能

4.1 创建Maven Module pinyougou-search-interface.jar
4.2 引入pinyougou-pojo模块
4.3 创建Maven Module pinyougou-search-service.war
4.4 引入pinyougou-search-interface接口和Spring相关依赖以及tomcat插件
4.5 添加web.xml配置文件
4.6 添加Spring相关配置文件

  applicationContext-service.xml

<dubbo:protocol name="dubbo" port="20884"></dubbo:protocol>
<dubbo:application name="pinyougou-search-service"/>  
<dubbo:registry address="zookeeper://192.168.25.131:2181"/>
<dubbo:annotation package="com.pinyougou.search.service.impl" />  

4.7 添加Solr相关配置文件

  applicationContext-solr.xml

<!-- solr服务器地址 -->
<solr:solr-server id="solrServer" url="http://127.0.0.1:8080/solr" />
<!-- solr模板,使用solr模板可对索引库进行CRUD的操作 -->
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
	<constructor-arg ref="solrServer" />
</bean>

4.8 引入Solr相关依赖

  由于service工程依赖于interface工程,interface工程又依赖于pojo工程,而pojo工程引入了Solr的相关依赖,所以依赖传递过来了。这里就不用配置了。

4.9 在interface工程下创建com.pinyougou.search.service.ItemSearchService

  现在需要定义方法,这个方法干嘛的呢?肯定要满足我们搜索的需要。我们搜索东西,目前接收的是一个keywords字符串,返回的是一个列表。我们先这样定义:public List search(String keywords);。但是问题来啦,这个方法我们现在这么做没有问题,但是我们后期搜索的时候,传递过来的不仅仅是一个关键字了,我还有可能传分类,品牌,各种规格以及价格区间,这些数据,它作为一个组合的方式传递过来的。所以如果我们以组合的方式传递过来的时候,那么参数写一个keywords是不是就不够用了?这个时候我们可以传递一个更通用的东西Map searchMap就行了,这样所有的参数就可以组装之后再通过这个Map再传过来。这时候再看返回值,返回List够用吗?因为搜索一个东西返回的仍然包括分类,品牌,各种规格以及价格区间,这些数据。所以这里还可以用Map返回就没有问题了。所以最终的方法是这样的:public Map search(Map searchMap);

4.10 在service工程下创建com.pinyougou.search.service.impl.ItemSearchServiceImpl

@Service
public class ItemSearchServiceImpl implements ItemSearchService {

	// 通过SolrTemplate对Solr操作
	@Autowired
	private SolrTemplate solrTemplate;
	
	@Override
	public Map search(Map searchMap) {
		Map map = new HashMap();
		Query query = new SimpleQuery("*:*");
		// 这里的参数和配置的域中的name保持一致。
		// 这里采用复制域的方式,可以匹配多个字段。
		Criteria criteria = new Criteria("item_keywords");
		// is:匹配,因为它是经过分词以后的,所以查询的时候它肯定也是一个词。直接匹配关键字
		criteria.is(searchMap.get("keywords"));
		query.addCriteria(criteria );
		// 通过solrTemplate查询solr索引库中的内容
		ScoredPage<TbItem> page = solrTemplate.queryForPage(query , TbItem.class);
		// 将当前页的数据封装到一个map里,这个rows就是搜索的列表
		map.put("rows", page.getContent());
		return map;
	}
}

4.11 在web工程下创建com.pinyougou.search.controller.ItemSearchController

@RestController
@RequestMapping("/itemsearch")
public class ItemSearchController {
	@Reference
	private ItemSearchService ItemSearchService;
	
	@RequestMapping("/search")
	public Map search(@RequestBody Map searchMap) {
		return ItemSearchService.search(searchMap);
	}
}

细节知识点
这个细节知识点其实和Solr没什么关系,但是加上这个可以防止出现一些问题。这个知识点其实是Dubbox的知识点。也就是说在我们执行这个搜索的时候有可能它这个时间比较长,那么比较长的情况下会造成什么问题呢?或造成调用的一个超时。也就是控制层去掉服务层,然后服务层去调Solr,但是这个过程很可能是超过1秒钟的,但是Dubbox默认情况下是超过1秒它就会报一个超时的错误,但是有时候有可能会超过1秒钟的时间,这个取决于我们的服务器的性能。比如说我们的服务器内存比较小,或者说并发比较高,那也会比较慢。这个时候我们可以在@Reference注解上设置一下我们的超时时间:(timeout=5000),超过5秒才会报异常。其实也可以在我们的服务端去添加。在@Service注解上加上(timeout=5000)推荐放到服务端,因为服务的提供者比服务的调用者更清楚这个业务的执行性能。如果控制端和服务端都配置了,则以控制端的消费方为准。

4.12 编写servicejscontrollerjs

// 定义品优购模块
var app = angular.module("pinyougou", []);
app.service("searchService", function($http){
	// 搜索方法
	this.search = function(searchMap) {
		// post提交
		return $http.post("itemsearch/search.do", searchMap);
	}
});
app.controller("searchController", function($scope, searchService){
	$scope.search = function() {
		// $scope.searchMap是页面上传过来的,在页面上要进行绑定
		searchService.search($scope.searchMap).success(function(response) {
			console.log(response);
			// 因为response可能是一个多元化的一个东西,
			// 所以resultMap是一个对象,并不是一个集合
			$scope.resultMap = response;
		})
	}
});

4.13 页面引入js,绑定…

<!-- 引入angular -->
<script type="text/javascript" src="plugins/angularjs/angular.min.js"></script>
<script type="text/javascript" src="js/base.js"></script>
<script type="text/javascript" src="js/service/searchService.js"></script>
<script type="text/javascript" src="js/controller/searchController.js"></script>

搜索框:

<!-- searchMap.keywords绑定该对象的一个属性,这个属性是在后台service层定义好的字段名 -->
<input type="text" id="autocomplete" type="text" ng-model="searchMap.keywords"
	class="input-error input-xxlarge" />
<!-- ng-click调用search方法 -->
<button class="sui-btn btn-xlarge btn-danger" ng-click="search()" 
    type="button">搜索</button>

搜索结果,绑定在resultMaprows里:

<li class="yui3-u-1-5" ng-repeat="item in resultMap.rows">
	<div class="list-wrap">
		<div class="p-img">
			<a href="item.html" target="_blank">
				<img src="{{item.image}}" />
			</a>
		</div>
		<div class="price">
			<strong>
				<em>¥</em>
				<i>{{item.price}}</i>
			</strong>
		</div>
		<div class="attr">
			<em>{{item.title}}</em>
		</div>		
	</div>
</li>

下一节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值