Solr是一个独立的企业级搜索应用服务器,它对外提供相似于Web-service的API接口。用户能够经过http请求,向搜索引擎服务器提交必定格式的XML文件,生成索引;也能够经过Http Get操做提出查找请求,并获得XML格式的返回结果。php
Solr是Apache软件基金会下的子项目之一。java
solr是基于Lucence开发的企业级搜索引擎技术,而lucence的原理是倒排索引。那么什么是倒排索引呢?接下来咱们就介绍一下lucence倒排索引原理。json
假设有两篇文章1和2:服务器
文章1的内容为:老超在卡子门工做,我也是。ide
文章2的内容为:小超在鼓楼工做。ui
因为lucence是基于关键词索引查询的,那咱们首先要取得这两篇文章的关键词。若是咱们把文章当作一个字符串,咱们须要取得字符串中的全部单词,即分词。分词时,忽略”在“、”的“之类的没有意义的介词,以及标点符号能够过滤。搜索引擎
咱们使用Ik Analyzer实现中文分词,分词以后结果为:url
文章1:指针
文章2:code
接下来,有了关键词后,咱们就能够创建倒排索引了。上面的对应关系是:“文章号”对“文章中全部关键词”。倒排索引把这个关系倒过来,变成: “关键词”对“拥有该关键词的全部文章号”。
文章一、文章2通过倒排后变成:
一般仅知道关键词在哪些文章中出现还不够,咱们还须要知道关键词在文章中出现次数和出现的位置,一般有两种位置:
a.字符位置,即记录该词是文章中第几个字符(优势是关键词亮显时定位快);
b.关键词位置,即记录该词是文章中第几个关键词(优势是节约索引空间、词组(phase)查询快),lucene中记录的就是这种位置。
加上出现频率和出现位置信息后,咱们的索引结构变为:
实现时,lucene将上面三列分别做为词典文件(Term Dictionary)、频率文件(frequencies)、位置文件 (positions)保存。其中词典文件不只保存有每一个关键词,还保留了指向频率文件和位置文件的指针,经过指针能够找到该关键字的频率信息和位置信息。
使用SolrJ能够实现索引库的增删改查操做。
第一步:把solrJ的jar包添加到工程中。
第二步:建立一个SolrServer,使用HttpSolrServer建立对象。
第三步:建立一个文档对象SolrInputDocument对象。
第四步:向文档中添加域。必须有id域,域的名称必须在schema.xml中定义。
第五步:把文档添加到索引库中。
第六步:提交。
@Test public void testSolrJAdd() throws SolrServerException, IOException { // 建立一个SolrServer对象。建立一个HttpSolrServer对象 // 须要指定solr服务的url SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1"); // 建立一个文档对象SolrInputDocument SolrInputDocument document = new SolrInputDocument(); // 向文档中添加域,必须有id域,域的名称必须在schema.xml中定义 document.addField("id", "123"); document.addField("item_title", "红米手机"); document.addField("item_price", 1000); // 把文档对象写入索引库 solrServer.add(document); // 提交 solrServer.commit(); }
第一步:建立一个SolrServer对象。
第二步:调用SolrServer对象的根据id删除的方法。
第三步:提交。
@Test public void deleteDocumentById() throws Exception { SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1"); solrServer.deleteById("123"); // 提交 solrServer.commit(); }
@Test public void deleteDocumentByQuery() throws Exception { SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1"); //这边会根据分词去删 solrServer.deleteByQuery("item_title:红米手机"); solrServer.commit(); }
第一步:建立一个SolrServer对象
第二步:建立一个SolrQuery对象。
3 向SolrQuery中添加查询条件、过滤条件。。。
第四步:执行查询。获得一个Response对象。
5 取查询结果。
第六步:遍历结果并打印。
@Test public void queryDocument() throws Exception { // 第一步:建立一个SolrServer对象 SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1"); // 第二步:建立一个SolrQuery对象。 SolrQuery query = new SolrQuery(); // 第三步:向SolrQuery中添加查询条件、过滤条件。。。 query.setQuery("*:*"); // 第四步:执行查询。获得一个Response对象。 QueryResponse response = solrServer.query(query); // 第五步:取查询结果。 SolrDocumentList solrDocumentList = response.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_price")); } }
@Test public void searchDocumet() throws Exception { // 建立一个SolrServer对象 SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1"); // 建立一个SolrQuery对象 SolrQuery query = new SolrQuery(); // 设置查询条件、过滤条件、分页条件、排序条件、高亮 // query.set("q", "*:*"); query.setQuery("手机"); // 分页条件 query.setStart(0); query.setRows(30); // 设置默认搜索域 query.set("df", "item_keywords"); // 设置高亮 query.setHighlight(true); // 高亮显示的域 query.addHighlightField("item_title"); query.setHighlightSimplePre("<div>"); query.setHighlightSimplePost("</div>"); // 执行查询,获得一个Response对象 QueryResponse response = solrServer.query(query); // 取查询结果 SolrDocumentList solrDocumentList = response.getResults(); // 取查询结果总记录数 System.out.println("查询结果总记录数:" + solrDocumentList.getNumFound()); for (SolrDocument solrDocument : solrDocumentList) { System.out.println(solrDocument.get("id")); // 取高亮显示 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"); } System.out.println(itemTitle); 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")); System.out.println("============================================="); } }
这个实际上是经过图形界面操做,只需手动填写查询条件,不须要进行代码处理。可是实际项目开发中,仍是须要进行代码编写的。
q 查询的关键字,此参数最为重要,例如,q=id:1,默认为q=*:*, fq (filter query)过虑查询,提供一个可选的筛选器查询。 返回在q查询符合结果中同时符合的fq条件的查询结果 sort 排序方式,例如id desc 表示按照 “id” 降序 start 返回结果的第几条记录开始,通常分页用,默认0开始 rows 指定返回结果最多有多少条记录,默认值为 10,配合start实现分页 fl 指定返回哪些字段,用逗号或空格分隔,注意:字段区分大小写,例如,fl= id,title,sort df 默认的查询字段,通常默认指定 wt (writer type)指定输出格式,有 xml, json, php等 indent 返回的结果是否缩进,默认关闭 hl 高亮 hl.fl 设定高亮显示的字段 hl.requireFieldMatch 若是置为true,除非用hl.fl指定了该字段,查询结果才会被高亮。它的默认值是false。 hl.usePhraseHighlighter 若是一个查询中含有短语(引号框起来的)那么会保证必定要彻底匹配短语的才会被高亮。 hl.highlightMultiTerm若是使用通配符和模糊搜索,那么会确保与通配符匹配的term会高亮。默认为false,同时hl.usePhraseHighlighter要为true。 hl.fragsize 返回的最大字符数。默认是100.若是为0,那么该字段不会被fragmented且整个字段的值会被返回。