Lucene笔记48-Lucene-Solr的基本应用

一、SolrJ的使用

  1. 导入相关jar包,打开solr-3.5/dist/solrj-lib,找到下面五个文件:commons-codec-1.5.jar,commons-httpclient-3.1.jar,commons-io-1.4.jar,jcl-over-slf4j-1.5.5.jar,slf4j-api-1.5.5.jar。再找到dist路径下的apache-solr-core-3.5.0.jar和apache-solr-solrj.3.5.0.jar。
  2. 创建测试类SolrJTest.class。

二、相关代码

删除所有索引

CommonsHttpSolrServer commonsHttpSolrServer = new CommonsHttpSolrServer(solrServerUrl);
// 删除所有数据并提交
commonsHttpSolrServer.deleteByQuery("*:*");
commonsHttpSolrServer.commit();

创建文档

// 添加文档并提交
SolrInputDocument solrInputDocument = new SolrInputDocument();
// 添加Field的时候,这里必须有一个主键id,这里的类型也要是String的
solrInputDocument.addField("id", "1");
solrInputDocument.addField("title", "这是我的第一个SolrJ的程序");
// 会发现content这一行报错,为什么呢?因为在默认的schema.xml中没有content的field
// solrInputDocument.addField("content","这个程序能不能跑起来呢?");
commonsHttpSolrServer.add(solrInputDocument);
commonsHttpSolrServer.commit();

打开Luke查看分词结果,结果如下图,因为没有使用中文分词器,所以几乎没效果。

在schema.xml中加入自己定义的Field,并指定type为中文分词器的type。分别在types标签最上面和fields标签最上面加入下面的代码,标注IK分词器和自定义的域。重启Tomcat服务器。这里注意修改文件的时候别改错了,蠢蠢的我就改错了,改成了example中的schema.xml,这肯定不起作用啊,需要修改home下的schema.xml文件才生效。

<!--IK分词器,加在types最上面-->
<fieldType name="text" class="solr.TextField" >
  <analyzer type="index">
    <tokenizer class="org.wltea.analyzer.solr.IKTokenizerFactory" useSmart ="false"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="org.wltea.analyzer.solr.IKTokenizerFactory" useSmart ="false"/>
  </analyzer>
</fieldType>

<!-- 自定义的Field,加在fields最上面,这里的type="text"对应上面的name="text" -->
<field name="msg_title" type="text" store="true" indexed="true" />
<field name="msg_content" type="text" store="true" indexed="true" />

打开Luke查看结果,可以看到分词起作用了。

我们在搜索的时候,希望既搜索msg_title域,又搜索msg_content域,我们需要在Query String中输入“msg_title:程序 msg_content:程序”来实现or的效果,写法上还是比较麻烦的,所以Solr给我们提供了一个方法。在schema.xml的合适位置加上下面的代码。注意这里多了一个multiValued,这个multiValued别写错了,是大小写敏感的,一开始写成了multivalued,结果不起作用,这个的作用相当于把msg_content和msg_title拷贝到了msg_all中了。以后就使用msg_all来搜索了。重启Tomcat服务器。重新建立添加文档后,在Query String中输入“msg_all:程序”搜索就可以既查询title,又查询content了。

<!-- multiValued="true"表示这个域是允许多个值的 -->
<field name="msg_all" type="text" store="false" indexed="true" multiValued="true" />

<!-- 指定msg_all的copyField -->
<copyField source="msg_title" dest="msg_all" />
<copyField source="msg_content" dest="msg_all" />

可是,我们在搜索的时候,通常不会输入某个域吧?所以这里可以指定某个域是默认搜索域,即在schema.xml中搜索“defaultSearchField”节点。修改其中的值为“msg_all”,重启Tomcat,重新添加文档,在Query String中输入“程序”。发现可以搜索到,说明配置的默认域生效了。

三、项目代码

package com.wsy;

import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Test;

import java.io.IOException;
import java.net.MalformedURLException;

public class SolrJTest {
    private final static String solrServerUrl = "http://localhost:8080/solr";

    @Test
    public void test() {
        try {
            // 创建SolrServer对象(CommonsHttpSolrServer和EmbeddedSolrServer)
            // CommonsHttpSolrServer需要启动web服务器,通过HTTP请求获取数据
            // EmbeddedSolrServer是内嵌式的,可以不启动HTTP来获取数据,只需要导入包,指定home目录就可以了,但是底层还是依托于HTTP服务的
            CommonsHttpSolrServer commonsHttpSolrServer = new CommonsHttpSolrServer(solrServerUrl);
            // 删除所有数据并提交
            // commonsHttpSolrServer.deleteByQuery("*:*");
            // commonsHttpSolrServer.commit();
            // 添加文档并提交
            SolrInputDocument solrInputDocument = new SolrInputDocument();
            // 添加Field的时候,这里必须有一个主键id,这里的类型也要是String的
            // id是唯一主键,当有相同的id的时候,后面的会把前面的覆盖掉
            solrInputDocument.addField("id", "1");
            solrInputDocument.addField("msg_title", "这是我的第一个SolrJ的程序");
            solrInputDocument.addField("msg_content", "这个程序能不能跑起来呢?");
            commonsHttpSolrServer.add(solrInputDocument);
            commonsHttpSolrServer.commit();
            // 10分钟
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值