e3mall项目第七天——关于solr服务的搭建以及使用

今日内容一:Solr服务搭建

Solr服务器的搭建

今日内容二:使用solrJ管理索引库

使用SolrJ可以实现索引库的增删改查操作。
添加文档:
第一步:把solrJ的jar包添加到工程中。
第二步:创建一个SolrServer,使用HttpSolrServer创建对象。
第三步:创建一个文档对象SolrInputDocument对象。
第四步:向文档中添加域。必须有id域,域的名称必须在schema.xml中定义。
第五步:把文档添加到索引库中。
第六步:提交。
代码的实现:

     /*
	 * 添加文档
	 */
	@Test
	public void testSolrJ() throws SolrServerException, IOException{
		//创建一个SolrServer对象,创建一个链接,参数solr服务的url
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.129:8080/solr/collection1");
		//创建一个文档对象SolrInputDocument
		SolrInputDocument document = new SolrInputDocument();
		//向文档对象中添加域,文档中必须包含一个id域,所有的域的名称必须在schema.xml中定义。
		document.addField("id", "test001");
		document.addField("item_title", "测试商品");
		document.addField("item_price", "199");
		//把文档写入索引库
		solrServer.add(document);
		//提交
		solrServer.commit();
	}

删除文档:
实现代码:

     /*
	 * 通过id将文档删除
	 */
	@Test
	public void testSolr03() throws SolrServerException, IOException{
		//创建一个SolrServer对象,创建一个链接,参数solr服务的url
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.129:8080/solr/collection1");
		solrServer.deleteById("test001");
		solrServer.commit();
		
	}
/*
	 * 根据查询删除
	 */
	@Test
	public void testSolr02() throws SolrServerException, IOException{
		//创建一个SolrServer对象,创建一个链接,参数solr服务的url
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.129:8080/solr/collection1");
		solrServer.deleteByQuery("title:change.me");
		solrServer.commit();
		
	}

查询索引库

/**
	 * 使用sorlJ 简单查询索引库
	 * @throws SolrServerException 
	 */
	@Test
	public void queryIndex() throws Exception {
		//创建一个SolrServer对象。
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.163:8080/solr/collection1");
		//创建一个SolrQuery对象。
		SolrQuery query = new SolrQuery();
		//设置查询条件。
		//query.setQuery("*:*");
		query.set("q", "*:*");
		//执行查询,QueryResponse对象。
		QueryResponse queryResponse = solrServer.query(query);
		//取文档列表。取查询结果的总记录数
		SolrDocumentList solrDocumentList = queryResponse.getResults();
		System.out.println("查询结果总记录数:" + solrDocumentList.getNumFound());
		//遍历文档列表,从取域的内容。
		for (SolrDocument solrDocument : solrDocumentList) {
			System.out.println(solrDocument.get("id"));
			System.out.println(solrDocument.get("item_title"));
			System.out.println(solrDocument.get("item_sell_point"));
			System.out.println(solrDocument.get("item_price"));
			System.out.println(solrDocument.get("item_image"));
			System.out.println(solrDocument.get("item_category_name"));
		}
	}
//复杂查询
	@Test
	public void queryIndexFuza() throws Exception {
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.163:8080/solr/collection1");
		//创建一个查询对象
		SolrQuery query = new SolrQuery();
		//查询条件
		query.setQuery("手机");
		query.setStart(0);
		query.setRows(20);
		query.set("df", "item_title");
		query.setHighlight(true);
		query.addHighlightField("item_title");
		query.setHighlightSimplePre("<em>");
		query.setHighlightSimplePost("</em>");
		//执行查询
		QueryResponse queryResponse = solrServer.query(query);
		//取文档列表。取查询结果的总记录数
		SolrDocumentList solrDocumentList = queryResponse.getResults();
		System.out.println("查询结果总记录数:" + solrDocumentList.getNumFound());
		//遍历文档列表,从取域的内容。
		Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
		for (SolrDocument solrDocument : solrDocumentList) {
			System.out.println(solrDocument.get("id"));
			//取高亮显示
			List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
			String title = "";
			if (list !=null && list.size() > 0 ) {
				title = list.get(0);
			} else {
				title = (String) solrDocument.get("item_title");
			}
			System.out.println(title);
			System.out.println(solrDocument.get("item_sell_point"));
			System.out.println(solrDocument.get("item_price"));
			System.out.println(solrDocument.get("item_image"));
			System.out.println(solrDocument.get("item_category_name"));
		}
	}

今日内容三:把商品数据导入到索引库中

注意事项:所写的接口以及类需要发布到服务上,安装到本地仓库中,pojo需要实现序列化接口。需要将mapper.java类通过扫描包的形式,注入到spring容器中
<!-- 配置包扫描器 --> <context:component-scan base-package="cn.e3mall.search"/>

Dao层:sql语句

  	    SELECT
			a.id,
			a.title,
			a.sell_point,
			a.price,
			a.image,
			b. NAME category_name
		FROM
			tb_item a
		LEFT JOIN tb_item_cat b ON a.cid = b.id
		WHERE
			a.`status` = 1

.创建对应数据集的pojo在commo中

public class SearchItem implements Serializable{
	private String id;
	private String title;
	private String sell_point;
	private long price;
	private String image;
	private String category_name;

需要实现序列化接口,以及get,set方法。

接口定义

public interface ItemMapper {

	List<SearchItem> getItemList();
}

.Mapper映射文件

<mapper namespace="cn.e3mall.search.mapper.ItemMapper" >
  <select id="getItemList" resultType="cn.e3mall.common.pojo.SearchItem">
  	    SELECT
			a.id,
			a.title,
			a.sell_point,
			a.price,
			a.image,
			b. NAME category_name
		FROM
			tb_item a
		LEFT JOIN tb_item_cat b ON a.cid = b.id
		WHERE
			a.`status` = 1
  </select>
</mapper>

Service层:
SolrServer在applicationContext-solr的配置:

    <bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
		<constructor-arg index="0" value="http://192.168.25.129:8080/solr/collection1"/>
	</bean>
/**
 * 索引库维护Service
 * <p>Title: SearchItemServiceImpl</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Service
public class SearchItemServiceImpl implements SearchItemService {

	@Autowired
	private ItemMapper itemMapper;
	@Autowired
	private SolrServer solrServer;
	
	@Override
	public E3Result importAllItems() {
		try {
			//查询商品列表
			List<SearchItem> itemList = itemMapper.getItemList();
			//遍历商品列表
			for (SearchItem searchItem : itemList) {
				//创建文档对象
				SolrInputDocument document = new SolrInputDocument();
				//向文档对象中添加域
				document.addField("id", searchItem.getId());
				document.addField("item_title", searchItem.getTitle());
				document.addField("item_sell_point", searchItem.getSell_point());
				document.addField("item_price", searchItem.getPrice());
				document.addField("item_image", searchItem.getImage());
				document.addField("item_category_name", searchItem.getCategory_name());
				//把文档对象写入索引库
				solrServer.add(document);
			}
			//提交
			solrServer.commit();
			//返回导入成功
			return E3Result.ok();
		} catch (Exception e) {
			e.printStackTrace();
			return E3Result.build(500, "数据导入时发生异常");
					
		}
	}

}

controller层:

/**
 * 导入商品数据到索引库
 * <p>Title: SearchItemController</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class SearchItemController {
	
	@Autowired
	private SearchItemService searchItemService;

	@RequestMapping("/index/item/import")
	@ResponseBody
	public E3Result importItemList() {
		E3Result e3Result = searchItemService.importAllItems();
		return e3Result;
		
	}
}

注意:解决Mapper映射文件不存在异常
在e3-search-service的pom文件中需要添加资源配置。

<!-- 如果不添加此节点mybatis的mapper.xml文件都会被漏掉。 -->
	<build>
		<resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
	</build>

今日内容四:搜索功能实现

注意事项:
1.需要早common准备一个pojo,实现序列化接口

public class SearchResult implements Serializable{
	private long recordCount;
	private int totalPages;
	private List<SearchItem> itemList;
	}

2.需要一个配置文件resource.properties,用于展示一页显示多少条数据,加载配置文件

SEARCH_RESULT_ROWS=60
<!-- 加载配置文件 -->
	<context:property-placeholder location="classpath:conf/resource.properties" />

3.将接口和实现类发布服务:

<!-- 声明需要暴露的服务接口 -->
	<dubbo:service interface="cn.e3mall.search.service.SearchItemService" ref="searchItemServiceImpl" timeout="600000"/>
	<dubbo:service interface="cn.e3mall.search.service.SearchService" ref="searchServiceImpl" timeout="600000"/>

4.将solrServer对象交给spring容器管理applicationContext-solr.xml

    <bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
		<constructor-arg index="0" value="http://192.168.25.129:8080/solr/collection1"/>
	</bean>

dao层:
跟据查询条件查询索引库,返回对应的结果。
参数:SolrQuery
返回结果:SearchResult
代码实现;

/**
 * 商品搜索dao
 * <p>Title: SearchDao</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Repository
public class SearchDao {

	@Autowired
	private SolrServer solrServer;

	public SearchResult search(SolrQuery query) throws SolrServerException {
		// 根据query查询索引库
		QueryResponse queryResponse = solrServer.query(query);
		// 取查询结果。
		SolrDocumentList solrDocumentList = queryResponse.getResults();
		// 取查询结果总记录数
		long numFound = solrDocumentList.getNumFound();
		SearchResult result = new SearchResult();
		result.setRecordCount(numFound);
		// 取商品列表,需要取高亮显示
		Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
		List<SearchItem> itemList = new ArrayList<>();
		for (SolrDocument solrDocument : solrDocumentList) {
			SearchItem item = new SearchItem();
			item.setId((String) solrDocument.get("id"));
			item.setCategory_name((String) solrDocument.get("item_category_name"));
			item.setImage((String) solrDocument.get("item_image"));
			item.setPrice((long) solrDocument.get("item_price"));
			item.setSell_point((String) solrDocument.get("item_sell_point"));
			// 取高亮显示
			List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
			String title = "";
			if (list != null && list.size() > 0) {
				title = list.get(0);
			} else {
				title = (String) solrDocument.get("item_title");
			}
			item.setTitle(title);
			// 添加到商品列表
			itemList.add(item);
		}
		result.setItemList(itemList);
		// 返回结果
		return result;
	}
}

interface:

public interface SearchService {
	SearchResult search(String keyword,int page,int rows) throws Exception;
}

service;
需要有一个接口一个实现类,需要对外发布服务。
参数:String keyWord
int page
int rows
返回值:SearchResult
业务逻辑:
1)根据参数创建一个查询条件对象。需要指定默认搜索域,还需要配置高亮显示。
2)调用dao查询。得到一个SearchResult对象
3)计算查询总页数,每页显示记录数就是rows参数。

代码实现:

/**
 * 商品的搜索service
 * <p>Title: SearchServiceImpl</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Service
public class SearchServiceImpl implements SearchService {

	@Autowired
	private SearchDao searchDao;

	@Override
	public SearchResult search(String keyword, int page, int rows) throws Exception {
		// 创建一个SolrQuery对象
		SolrQuery query = new SolrQuery();
		// 设置查询条件
		query.setQuery(keyword);
		// 设置分页条件
		if (page <= 0) page = 1;
		query.setStart((page - 1) * rows);
		query.setRows(rows);
		// 设置默认搜索域
		query.set("df", "item_title");
		// 开启高亮显示
		query.setHighlight(true);
		query.addHighlightField("item_title");
		query.setHighlightSimplePre("<em style=\"color:red\">");
		query.setHighlightSimplePost("</em>");
		// 调用dao执行查询
		SearchResult searchResult = searchDao.search(query);
		// 计算总页数
		long recordCount = searchResult.getRecordCount();
		int totalPage = (int) (recordCount / rows);
		if (recordCount % rows > 0)
			totalPage++;
		// 添加到返回结果
		searchResult.setTotalPages(totalPage);
		// 返回结果
		return searchResult;
	}
}

controller层:
请求的url:/search
请求的方法:GET
参数:
keyword:查询条件
Page:页码。如果没有此参数,需要给默认值1。
返回的结果:
使用jsp展示,返回逻辑视图。

代码实现:

/**
 * 商品搜索的controller层
 * <p>Title: SearchConreoller</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class SearchConreoller {
	@Autowired
	private SearchService searchService;
	
	@Value("${SEARCH_RESULT_ROWS}")
	private Integer SEARCH_RESULT_ROWS;

	@RequestMapping("/search")
	public String searchItemList(String keyword, 
			@RequestParam(defaultValue="1") Integer page, Model model) throws Exception {
		keyword = new String(keyword.getBytes("iso-8859-1"), "utf-8");
		//查询商品列表
		SearchResult searchResult = searchService.search(keyword, page, SEARCH_RESULT_ROWS);
		//把结果传递给页面
		model.addAttribute("query", keyword);
		model.addAttribute("totalPages", searchResult.getTotalPages());
		model.addAttribute("page", page);
		model.addAttribute("recourdCount", searchResult.getRecordCount());
		model.addAttribute("itemList", searchResult.getItemList());
		
		//返回逻辑视图
		return "search";
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值