solr环境的搭建请参考:http://www.cnblogs.com/xiao-zhang-blogs/p/7327814.html
- 1. Solr不支持搜索中文,办法总会有的,添加中文分词器。中文分词器有:IKAnalyzer,mmseg4j等
a) 中文分词指的是将一个汉字序列切分成一个一个单独的词。分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。
b) 写个程序看一下效果。(IKAnalyzer)
代码:
package demo; import java.io.IOException; import java.io.StringReader; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.wltea.analyzer.core.IKSegmenter; import org.wltea.analyzer.core.Lexeme; public class Test { public static void main(String[] args) throws IOException { String text = "我爱你中国,厉害了,我的国。我爱你!"; int topWordsCount=4; Map<String,Integer> wordsFrenMaps=getTextDef(text); sortSegmentResult(wordsFrenMaps,topWordsCount); } public static Map getTextDef(String text) throws IOException { Map<String, Integer> wordsFren=new HashMap<String, Integer>(); IKSegmenter ikSegmenter = new IKSegmenter(new StringReader(text), true); Lexeme lexeme; while ((lexeme = ikSegmenter.next()) != null) { if(lexeme.getLexemeText().length()>1){ if(wordsFren.containsKey(lexeme.getLexemeText())){ wordsFren.put(lexeme.getLexemeText(),wordsFren.get(lexeme.getLexemeText())+1); }else { wordsFren.put(lexeme.getLexemeText(),1); } } } return wordsFren; } public static void sortSegmentResult(Map<String,Integer> wordsFrenMaps,int topWordsCount){ Iterator<Map.Entry<String,Integer>> wordsFrenMapsIterator=wordsFrenMaps.entrySet().iterator(); while (wordsFrenMapsIterator.hasNext()){ Map.Entry<String,Integer> wordsFrenEntry=wordsFrenMapsIterator.next(); System.out.println(wordsFrenEntry.getKey()+" 的次数为"+wordsFrenEntry.getValue()); } } }
效果:
在步骤1.2中教大家如何将中文分词器添加到solr中。
- 2. 创建core数据来源一共有三种情况,分别是:1、通过java直接写入。2、直接配置数据源。
a) 在E:solrhome目录下创建一个文件夹helloworld,将solr-6.6.0exampleexample-DIHsolrdb文件夹下的conf文件夹赋值到helloworld文件夹下,如下图:
b) 在solr的管理界面点击Core Admin,点击Add Core,输入name值为helloworld,instanceDir值为helloworld,其他项不用改。注意:填写的值必须为我们创建的文件夹的名称,否则报错。最后Add Core。
成功后:
c) 接下来,我们就在创建好的core中去写入数据。
i. 第一种,直接通过java程序写入。
代码如下:
package test; import java.io.IOException; import java.util.List; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrClient; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.util.NamedList; public class TestSolr { //solr的服务器地址 private final static String SOLR_URL = "http://localhost:8080/solr/"; /** * 往索引库添加文档 * @throws IOException * @throws SolrServerException */ public void addDoc() throws SolrServerException, IOException{ //获得一个solr服务端的请求,去提交 ,选择具体的某一个solr core //solr的服务器地址 //private final static String SOLR_URL = "http://localhost:8080/solr/"; HttpSolrClient solr = new HttpSolrClient(SOLR_URL + "helloworld"); try { //构造一篇文档 SolrInputDocument document = new SolrInputDocument(); //往doc中添加字段,在客户端这边添加的字段必须在服务端中有过定义 document.addField("id", "1"); document.addField("name", "你好"); document.addField("description", "前进的中国你好"); solr.add(document); solr.commit(); } finally{ solr.close(); } } /** * 根据id从索引库删除文档 */ public void deleteDocumentById() throws Exception { //选择具体的某一个solr core HttpSolrClient server = new HttpSolrClient(SOLR_URL+"helloworld"); //删除文档 // server.deleteById("3"); //删除所有的索引 server.deleteByQuery("*:*"); //提交修改 server.commit(); server.close(); } /** * 查询 * @throws Exception */ public void querySolr() throws Exception{ HttpSolrClient solrServer = new HttpSolrClient(SOLR_URL+"helloworld"); SolrQuery query = new SolrQuery(); // String temp = "name:文 OR description:你"; // query.setQuery(temp); //下面设置solr查询参数 //query.set("q", "*:*");// 参数q 查询所有 query.set("q","好");//相关查询,比如某条数据某个字段含有某个字 将会查询出来 ,这个作用适用于联想查询 //参数fq, 给query增加过滤查询条件 query.addFilterQuery("id:[0 TO 9]");//id为0-9 //参数df,给query设置默认搜索域 query.set("df", "name"); //参数sort,设置返回结果的排序规则 query.setSort("id",SolrQuery.ORDER.desc); //设置分页参数 query.setStart(0); query.setRows(10);//每一页多少值 //参数hl,设置高亮 query.setHighlight(true); //设置高亮的字段 query.addHighlightField("name"); //设置高亮的样式 query.setHighlightSimplePre("<font color='red'>"); query.setHighlightSimplePost("</font>"); //获取查询结果 QueryResponse response = solrServer.query(query); //两种结果获取:得到文档集合或者实体对象 //查询得到文档的集合 SolrDocumentList solrDocumentList = response.getResults(); //NamedList,一个有序的name/value容器,NamedList不像Map NamedList list = (NamedList) response.getResponse().get("highlighting"); System.out.println(list); System.out.println("查询的结果"); System.out.println("总数量:" + solrDocumentList.getNumFound()); //遍历列表 for (SolrDocument doc : solrDocumentList) { System.out.println("id:"+doc.get("id")+" name:"+doc.get("name")+" description:"+doc.get("description")); } } }
效果如下:
ii. 直接配置数据源(结构化数据存储)
- 如何将中文分词器加入到solr中
先下载mmseg4j的jar包,一共有三个,分别是:mmseg4j-analysis-1.9.1.jar、mmseg4j-core-1.10.0.jar和mmseg4j-solr-2.4.0.jar。
将mmseg4j-core-1.10.0.jar和mmseg4j-solr-2.4.0.jar放在apache-tomcat-8.0.32webappssolrWEB-INFlib目录下。
(注意:不要将包mmseg4j-analysis-1.9.1.jar放到改目录下,否则会报:java.lang.NoSuchMethodError: com.chenlb.mmseg4j.analysis.MMSegTokenizer.<init>(Lcom/chenlb/mmseg4j/Seg;)V错误信息,原因是:mmseg4j-solr已经包含了mmseg4j-analysis)
- 在core去配置。
没有加入中文分词器的效果,无论你选择哪种类型,得到的结果如下:
添加中文分词器:
首先mmseg4j有三种分词方式:
<!-- mmseg4j的三种分词方式--> <fieldtype name="textComplex" class="solr.TextField" positionIncrementGap="100"> <analyzer> <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="/dic"/> </analyzer> </fieldtype> <fieldtype name="textMaxWord" class="solr.TextField" positionIncrementGap="100"> <analyzer> <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="max-word" /> </analyzer> </fieldtype> <fieldtype name="textSimple" class="solr.TextField" positionIncrementGap="100"> <analyzer> <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" dicPath="G:ymysolrsolr-5.4.1serversolrgooddic" /> </analyzer> </fieldtype>
把这些添加到E:solrhomehelloworldconf的managed-schema文件的325行左右。
这个文件里面的field 标签里name存放的就是你所要分词的名称,type 放的是分词的类型。这里我把name=”title” 的type改为textComplex。(在148行)
重启tomcat,看一下效果(成功):
然后配置oracle数据源,这里我选用的表为books表
在managed-schema去添加字段类型和名称(author和name配置文件中有,修改一下type即可,id配置文件中也有,127行)
<field name="name" type="string" indexed="true" stored="true"/> <field name="author" type="string" indexed="true" stored="true"/> <field name="summary" type="string" indexed="true" stored="true"/> <field name="count" type="int" indexed="true" stored="true"/>
配置数据库映射:
首先,在E:solrhomehelloworldconf创建一个data-config.xml文件
文件内容:
<?xml version="1.0" encoding="UTF-8"?> <dataConfig> <dataSource name="source" type="JdbcDataSource" driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:orcl" user="scott" password="tiger"/> <document name="mydemo"> <entity name="mydemo" pk="id" dataSource="source" query="select * from books" transformer="ClobTransformer"> <field column="id" name="id" /> <field column="name" name="name" /> <field column="author" name="author"/> <field column="summary" name="summary" /> <field column="count" name="count"/> </entity> </document> </dataConfig>
接着在E:solrhomehelloworldconf的solrconfig.xml配置文件中的<requestHandler name="/select" class="solr.SearchHandler">(743行)上面添加
<requestHandler name="/dataimport" class="solr.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
将数据从数据库导入到helloworld的core中,如下图:
接着,查询全部:
数据成功导入。