15、solr基本使用(lucene笔记)

一、入门

在使用的时候需要和lucene的版本一致

1.1 安装

这里我们使用老版本的solr,解压之后使用命令:

java –jar  E:\API\Lucene\lucene3.5.0\apache-solr-3.5.0\example\start.jar

启动solr,然后使用地址http://localhost:8983/solr/admin访问solr。但是此时solr使用的是jetty服务器,我们首先让tomcat来管理solr,也就是使用tomcat来启动solr

步骤:

  • 1、我们在E:\API\Lucene中新建一个solr文件夹来保存solr相关的信息,同时在此solr文件夹中新建一个home文件夹,然后将solr解压目录中example下的solr文件夹中的内容拷贝到home文件夹中。拷贝之后将/home/data中的文件全部删除。

  • 2、将相应的solrweb程序(E:\API\Lucene\lucene3.5.0\apache-solr-3.5.0\example\webapps)中的solr.war拷贝到tomcat中,启动tomcat之后此文件会被解压,然后将tomcat中的solr.war删除。

  • 3、在home/conf/solrconfig.xml中配置

    15、solr基本使用(lucene笔记)_第1张图片
    1

    这里将我们的data文件夹的路径配置进去。

  • 4、设置相应的tomcatcontext
    E:\apache\tomcat\tomcat\conf\server.xml


    

2

说明:不知道是什么原因,如果不将 solr.war放在 tomcat\webapps中,当从 MyEclipse中启动 tomcat服务器的时候就会将这段添加的内容给删除掉。所以这里我们还是将这个 solr工程放在 tomcat\webapps中。

  • 5、Context设置相应的环境变量,说明solr的主目录的地址。如果启动有误,我们可以将E:\API\Lucene\solr\home\conf\solrconfig.xml中的这段注释掉。即取消Velocity的输出格式。
    3

    然后就可以使用地址http://localhost:8080/solr访问solr了。

2.2 添加中文分词器

  • 将中文分词的这两个包拷贝到solr服务器中的路径E:\API\Lucene\solr\server\solr\WEB-INF\lib中:
mmseg4j-solr-1.8.5.jar
mmseg4j-all-1.8.5.jar
  • 下面我们添加了三个MMSEG的分词的分词器到solrE:\API\Lucene\solr\home\conf\schema.xml

      
        
      
    
    
      
        
      
    
    
      
        
      
    

注意:最后一个绝对路径改成相对路径

15、solr基本使用(lucene笔记)_第2张图片
4

MMSEG中的数据( E:\API\Lucene\mmseg\data)拷贝到 solr服务器中( E:\API\Lucene\solr\home\dic),其中 dic是自己新建的一个目录。

注意:如果想在solr中使用中文,即让中文生效,必须在tomcat中进行指明:

2.3 入门程序(工程solr01

  • 1、需要的依赖包
commons-codec-1.5.jar
commons-httpclient-3.1.jar
commons-io-1.4.jar
jcl-over-slf4j-1.6.1.jar
slf4j-api-1.6.1.jar
apache-solr-solrj-3.5.0.jar
apache-solr-core-3.5.0.jar

注意:不需要加入lucene的相关包,以免冲突。

  • 2、测试程序
    SolrTest.java
package cn.solr.test;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Before;
import org.junit.Test;

public class SolrTest {
    
    private final static String URL = "http://localhost:8080/solr";
    
    @Test
    public void test01(){
        //创建一个solr服务器SolrServer对象(CommonsHttpSolrServer, EmbeddedSolrServer)
        //第一个是需要启动web服务器,后一个是内嵌式的
        try {
            CommonsHttpSolrServer  server = new CommonsHttpSolrServer(URL);
            //server.deleteByQuery("*:*");//这里的“*:*”就表示将源服务器中的所有文档索引全部删除
            //server.commit();//需要提交才能真正删除
            SolrInputDocument sdoc = new SolrInputDocument();
            //这一下面所有添加的域都必须在schema文件中添加,否则会报错
            //id是唯一的主键,当多次添加的时候,最后添加的相同的id域会覆盖前面的域
            sdoc.addField("id", "1");//id是什么类型的我们可以在schema.xml文件中查看
            sdoc.addField("title", "第一个solrJ的程序");
            //sdoc.addField("msg_title", "第一个solrJ的程序");
            //sdoc.addField("msg_content", "不知道这个程序能不能正确执行");
            
            //sdoc.addField("text", "测试默认域");//默认搜索的域为text
            server.add(sdoc);
            server.commit();
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

说明:然后我们在页面中使用命令*:*查询所有可以查询出我们刚才添加的索引。我们还可以使用命令title:第一来进行查询,发现也是可以查询到的。但是我们使用luke进行查看(生成的索引文件放在E:\API\Lucene\solr\home\data\index中),发现是没有进行中文分词的(因为默认使用的是lucene的标准分词器),此时我们可以修改E:\API\Lucene\solr\home\conf\schema.xml文件来让其使用我们添加的中文分词器(MMSEG)。在这里我们添加自己的域:





5

注意:在程序中添加域的时候需要将名字对应:

sdoc.addField("msg_title", "第一个solrJ的程序");

此时我们再次运行测试程序,然后使用luke查询索引,此时会发现进行了中文分词。同时注意:后面添加的索引会将前面的覆盖掉,也就是之前的title索引内容没有了。

3、添加复合域
我们经常需要对标题和内容同时查询,使用命令:

msg_title:第一  msg_content:不知道

但是这样显然很麻烦,我们可以在schema.xml文件中进行修改

6

添加了:


同时加上




7

也就是将 msg_titlemsg_content两个域中的内容都拷贝到 msg_all中了,就可以使用 msg_all进行搜索了。然后我们重建索引。
8

15、solr基本使用(lucene笔记)_第3张图片
9

我们如果想不加 msg_all则可以这样,先看下面这行代码:

sdoc.addField("text", "测试默认域");//默认搜索的域为text

然后我们可以进行搜索,不需要在前面加上域,发现是可以搜索到的,这是因为text是默认搜索的域,如果我们想不加msg_all则可以将schema.xml中的这个域换成msg_all,这样msg_all便成了默认搜索的域,就不需要加上索引前缀。

三、添加文档(工程solr2

添加文档有两种方式,一种是像上面那样直接添加;一种是基于javabean的添加。
对于直接添加,这里其实还有一种基于列表的添加:

package cn.solr.test;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Before;
import org.junit.Test;

public class SolrTest {
    
    private final static String URL = "http://localhost:8080/solr";
    private CommonsHttpSolrServer server = null;
    
    @Before
    public void init(){
        try {
            server = new CommonsHttpSolrServer(URL);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
    
    @Test
    public void test02(){
        try {
            //基于列表的添加
            List docs = new ArrayList();
            SolrInputDocument sdoc = new SolrInputDocument();
            sdoc.addField("id", "2");
            sdoc.addField("msg_title", "很好,solr终于工作了");
            sdoc.addField("msg_content", "solr总算可以正式工作了");
            docs.add(sdoc);
            
            sdoc = new SolrInputDocument();
            sdoc.addField("id", "3");
            sdoc.addField("msg_title", "测试solr添加");
            sdoc.addField("msg_content", "看能不能添加一个列表信息");
            docs.add(sdoc);
            
            server.add(docs);
            server.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

说明:这里我们先将每个文档添加到列表中,然后基于列表的添加,测试结果为:

15、solr基本使用(lucene笔记)_第4张图片
10

下面看基于javabean的添加
首先我们创建一个java对象
Message.java

package cn.solr.test;
import org.apache.solr.client.solrj.beans.Field;

public class Message {
    private String id ;
    private String title ;
    private String[] content ;
    
    public Message(){}
    
    public Message(String id, String title, String[] content) {
        this.id = id;
        this.title = title;
        this.content = content;
    }

    public String getId() {
        return id;
    }
    @Field
    public void setId(String id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    @Field("msg_title")
    public void setTitle(String title) {
        this.title = title;
    }
    public String[] getContent() {
        return content;
    }
    @Field("msg_content")
    public void setContent(String[] content) {
        this.content = content;
    }   
}

测试方法:

    @Test
    public void test03() {
        try {
            // 基于列表的添加
            List msgs = new ArrayList();
            msgs.add(new Message("4", "基于 java bean 的添加", new String[] {
                    "通过 java bean 完成添加", " java bean 的添加附件" }));
            msgs.add(new Message("5", "基于 java bean 的列表数据添加", new String[] {
                    "测试一下", "测试两下" }));
            server.addBeans(msgs);
            server.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

说明:测试结果为:

15、solr基本使用(lucene笔记)_第5张图片
11

这里因为 content域为一个数组,所以我们需要为其设置: multiValued="true"

四、搜索

    @Test
    public void test04() {
        //定义查询字符串
        //SolrQuery query = new SolrQuery("msg_all:测试");
        SolrQuery query = new SolrQuery("*:*");//查询所有
        query.setStart(0);//设置查询的起始点
        query.setRows(2);//设置每次查询到的条数
        try {
            //查询出来的结果都保存在SolrDocument中
            QueryResponse resp = server.query(query);
            SolrDocumentList sdl = resp.getResults();
            for(SolrDocument sd : sdl){
                System.out.println(sd);
                System.out.println(sd.getFieldValue("msg_title"));
            }
            System.out.println(sdl.getNumFound());//查询到的数据总条数
            
        } catch (SolrServerException e) {
            e.printStackTrace();
        }
    }
    
    @Test
    public void test05() {
        //SolrQuery query = new SolrQuery("msg_all:测试");
        SolrQuery query = new SolrQuery("*:*");//查询所有
        query.setStart(0);//设置查询的起始点
        query.setRows(2);//设置每次查询到的条数
        try {
            QueryResponse resp = server.query(query);
            //可以直接查询响应的bean对象,但是不是很常用
            List list = resp.getBeans(Message.class);//将查询到的数据转换成java对象
            System.out.println(list.size());
            for(Message m : list){
                System.out.println(m.getTitle());
            }
            
        } catch (SolrServerException e) {
            e.printStackTrace();
        }
    }

说明:这里我们给出两种查询,第一种是基于结果集的查询,这种查询是常用的,我们可以使用此种方式进行分页、高亮等操作,而第二种是基于javabean的查询,我们可以直接将查询到的结果转换成java对象,但是这种查询不常用,因为不能取得获取查询的总数量。同时对于content,如果我们设置让其存储,那么是可以查询到的。

五、高亮

    @Test
    public void test06() {
        SolrQuery query = new SolrQuery("msg_all:测试");
        // 设置高亮
        query.setHighlight(true)
                .setHighlightSimplePre("")
                .setHighlightSimplePost("").setStart(0).setRows(2);
        query.setParam("hl.fl", "msg_title,msg_content");//设置高亮的区域
        try {
            QueryResponse resp = server.query(query);
            SolrDocumentList sdl = resp.getResults();
            for (SolrDocument sd : sdl) {
                String id = (String) sd.getFieldValue("id");
                //注意:如果content域不存储,则是不能高亮的
                System.out.println(resp.getHighlighting().get(id).get("msg_content"));
            }

        } catch (SolrServerException e) {
            e.printStackTrace();
        }
    }

说明:这里要注意的是,对于想要高亮的域必须让其高亮,否则是不能高亮的。测试结果:

12

你可能感兴趣的:(15、solr基本使用(lucene笔记))