|
用SOLR搭建企利业搜索平台 之一(运行solr)
关键字: solr 搭建 lucene http://www.dzxiaoshuo.com
http://www.dzxiaoshuo.com
在网络上找了很多的关于solr的资料,发现非常的不全面,即使就是官方的wiki,也是如此!
基于现阶段正在研究的solr应用,陆续的会分享我的一些经验!
今天要说的是: 怎么跑起来!
1》 首先下载好solr,我用的是 solr1.3,下载地址:
windows版本http://labs.xiaonei.com/apache-mirror/lucene/solr/1.3.0/apache-solr-1.3.0.zip
linux版本http://labs.xiaonei.com/apache-mirror/lucene/solr/1.3.0/apache-solr-1.3.0.tgz
2》准备运行容器,我用的是tomcat6.0.20.如果是玩的话,也可以不用准备专门的容易,你只需解压好solr的下载包,找到example文件夹,然后运行 start.jar。具体指令:java -jar start.jar做应用的时候,不建议采用该方式。该方式内部包含了jetty!
3》有关tomcat的使用,不是本文的重点,如果你有问题,请参见tomcat的使用。解压好tomcat,将solr包下面的dist文件夹中的apache-solr-1.3.0.war 拷贝到 tomcat的webapps,并且改名为 solr.war。
4》新建一个 solr-tomcat文件夹,我是把这个文件夹建立在C盘根目录,你可以采用同样方式,也可以不这样,放哪由你决定。 建立好该文件夹以后,在把它下面在建立一个solr文件夹,把solr包里面的example\solr文件夹下面的所有文件放入到 solr里面。
5》最后一步 配置 solr.home,可以有三种方式。
1)基于当前路径的方式
这种情况需要在c:\solr-tomcat\目录下去启动tomcat,Solr查找./solr,因此在启动时候需要切换到c:\solr-tomcat\
2)基于环境变量
windows在环境变量中建立solr.home,值为c:\solr-tomcat
linux在当前用户的环境变量中(.bash_profile)或在catalina.sh中添加如下环境变量
export JAVA_OPTS="$JAVA_OPTS -Dsolr.solr.home=/opt/solr-tomcat/solr"
3)基于JNDI
在tomcat的conf文件夹建立Catalina文件夹,然后在Catalina文件夹中在建立localhost文件夹,在该文件夹下面建立solr.xml,其中内容:
Xml代码
问题描述:个人发现的一个问题,就是如果配置好JNDI的话,然后在tomcat的bin文件夹下面启动tomcat的话,会在tomcat的bin下面建立solr文件夹,这个文件夹中主要存放的索引文件。 本来这些东西应该放入c:\solr-tomcat\solr。如果你不想出现这种情况的话,请使用基于当前路径的方式。
6》打开浏览器,请看看能否访问该服务。如果能够访问,恭喜您跑起来了。
这篇文章,主要说的是 怎么在solr中加入中文分词,参考了一些文章,但是还是花了不少时间才搞出的。可能是大侠们太牛了,所以很多细节东西都没有写出来!但是要指出的是很多文章都是抄来抄去的!
入正题:
在上面的一个文章中,已经使solr跑起来了,在上面的基础上,加入中文分词。我用的是paoding分词器!
1》请下好paoding分词器,下载地址:
http://code.google.com/p/paoding/downloads/list,在这里要非常感谢paoding作者:qieqie
在使用paoding的时候要注意:paoding的dic位置,也就是字典的位置,有两种办法解决:
1) 在系统环境变量中加入PAODING_DIC_HOME这个变量,值为paoding压缩包下面的dic的解压位置。
2)paoding-analysis.jar里面有个paoding-dic-home.properties文件,指定dic也可,但是要重新编译这个jar包,我采用的后面一种办法,只要每次固定好dic位置,部署还不是很不方便,设置环境变量我比较反感
2》建立文件
Java代码
利用SOLR搭建企业搜索平台 之四(MultiCor ... | 利用SOLR搭建企业搜索平台 之二(中文分词 ...
2009-07-13
利用SOLR搭建企业搜索平台 之三(配置文件)
关键字: solr lucene 搭建 配置 http://www.dzxiaoshuo.com
http://www.dzxiaoshuo.com
运行solr是个很简单的事,如何让solr高效运行你的项目,这个就不容易了。要考虑的因素太多。这里很重要一个就是对solr的配置要了解。懂得配置文件每个配置项的含义,这样操作起来就会如鱼得水!
在solr里面主要的就是solr的主目录下面的schema.xml,solrConfig.xml,如果你看过前两篇文章的话,你应该知道solr的主目录处于什么位置(c:\solr-tomcat\solr\conf\)。
在这个文章中,我们首先来说说这个schema.xml。
schema.xml,这个相当于数据表配置文件,它定义了加入索引的数据的数据类型的。主要包括types、fields和其他的一些缺省设置。
1》首先需要在types结点内定义一个FieldType子结点,包括name,class,positionIncrementGap等等一些参数,name就是这个FieldType的名称,class指向org.apache.solr.analysis包里面对应的class名称,用来定义这个类型的行为。在FieldType定义的时候最重要的就是定义这个类型的数据在建立索引和进行查询的时候要使用的分析器analyzer,包括分词和过滤。在例子中text这个FieldType在定义的时候,在index的analyzer中使用 solr.WhitespaceTokenizerFactory这个分词包,就是空格分词,然后使用 solr.StopFilterFactory,solr.WordDelimiterFilterFactory,solr.LowerCaseFilterFactory,solr.EnglishPorterFilterFactory,solr.RemoveDuplicatesTokenFilterFactory 这几个过滤器。在向索引库中添加text类型的索引的时候,Solr会首先用空格进行分词,然后把分词结果依次使用指定的过滤器进行过滤,最后剩下的结果才会加入到索引库中以备查询。Solr的analysis包并没有带支持中文的包,在第二篇文章中详细讲了怎样添加paoding中文分词器,详情请参见http://lianj-lee.javaeye.com/blog/424474
2》接下来的工作就是在fields结点内定义具体的字段(类似数据库中的字段),就是field,field定义包括name,type(为之前定义过的各种FieldType),indexed(是否被索引),stored(是否被储存),multiValued(是否有多个值)等等。
例:
Xml代码
field的定义相当重要,有几个技巧需注意一下,对可能存在多值得字段尽量设置multiValued属性为true,避免建索引是抛出错误;如果不需要存储相应字段值,尽量将stored属性设为false。
3》建议建立了一个拷贝字段,将所有的全文字段复制到一个字段中,以便进行统一的检索:
Xml代码
并在拷贝字段结点处完成拷贝设置:
Xml代码
4》除此之外,还可以定义动态字段,所谓动态字段就是不用指定具体的名称,只要定义字段名称的规则,例如定义一个dynamicField,name 为*_i,定义它的type为text,那么在使用这个字段的时候,任何以_i结尾的字段都被认为是符合这个定义的,例如:name_i,gender_i,school_i等。
schema.xml配置文件大体上就是这样,更多细节请参见solr wiki http://wiki.apache.org/solr/SchemaXml。如果以后有时间,我会定时更新这篇文章,以争取能让更多初学者带来便利。
下篇文章将会讲到 solrConfig.xml,欢迎您留意!
- 11:38
- 浏览 (306)
- 评论 (2)
- 分类: solr
- 相关推荐
评论
2 楼 lianj_lee 2009-08-12 引用
290697743 写道
您好!
上面这段代码中为什么type="keyword_text"。
我在types节点的里面没有找到name="keyword_text" 的FieldType子节点
麻烦解答一下!谢谢!
不好意思,我并没有把这个文件贴出来,只是贴了要做定义的那块。我用的是solr-1.3
1 楼 290697743 2009-08-11 引用
Solr Multicore 是 solr 1.3 的新特性。其目的一个solr实例,可以有多个搜索应用。
下面着手来将solr给出的一个example跑出来,在《利用SOLR搭建企业搜索平台 之一(运行solr)》这篇文章里面已经讲了怎样来运行solr,这篇文章是基于《利用SOLR搭建企业搜索平台 之一(运行solr)》,有不明白的请参见http://lianj-lee.javaeye.com/blog/424383
1》找到solr下载包中的example文件夹,在它的下面有个multicore文件夹,将这个文件夹下面的所有东西copy到 c:\solr-tomcat\solr下面。
注意:有一个 solr.xml(这只是默认文件,当然也可以指定别的文件),如:
Xml代码
这个文件是告诉solr应该加载哪些core,cores里有 core0,core1。core0(可以类比以前的solr.home)/conf目录下有schema.xml与solrconfig.xml,可以把实际应用的复制过来。现示例就用官方的了。
2》启动tomcat,访问应用,就可以看到有 Admin core0 和 Admin core1
3》采用上面的默认solr.xml,索引文件将存放在同一个目录下面,在这里将存放在C:\solr-tomcat\solr\data,如果你想更改目录,或者两个应用存放在不同的目录,请参见下面的xml。
Xml代码
给core添加子元素 property,property的两个属性就不说了,一看就能明白!
solr.core.name -- The core's name as defined in solr.xml
solr.core.instanceDir -- The core's instance directory (i.e. the directory under which that core's conf/ and data/ directory are located)
solr.core.dataDir -- The core's data directory (i.e. the directory under which that core's index directory are located)
solr.core.configName -- The name of the core's config file (solrconfig.xml by default)
solr.core.schemaName -- The name of the core's schema file (schema.xml by default)
4》solr.xml具体含义:
1)solr
The tag accepts two attributes:
persistent - By default, should runtime core manipulation be saved in solr.xml so that it is available after a restart.
sharedLib - Path to a directory containing .jar files that are added to the classpath of every core. The path is relative to solr.home (where solr.xml sits)
2)cores
The tag accepts two attribute:
adminPath - Relative path to access the CoreAdminHandler for dynamic core manipulation. For example, adminPath="/admin/cores" configures access via http://localhost:8983/solr/admin/cores. If this attribute is not specified, dynamic manipulation is unavailable.
3)core
The tag accepts two attributes:
name - The registered core name. This will be how the core is accessed.
instanceDir - The solr.home directory for a given core.
dataDir - The data directory for a given core. The default is /data . It can take an absolute path or a relative path w.r.t instanceDir . Solr1.4
4)property
The tag accepts two attributes:
name - The name of the property
value - The value of the property
由于E文过于简单,所以就不翻译了!
有关更具体的solr.xml的配置,请参见solr wiki http://wiki.apache.org/solr/CoreAdmin。 已经讲的非常清楚,我就不多说了!
相信很多人,在准备提交数据让solr建立索引的那刻,很纳闷,尽管看了不少网上的一些文章,但是我想依然还是有不少不理解的地方。
比如提交一个xml,采用post方式,尽管有些文章说了可以采用httpclient。但是我那个时候,还不是很理解,当然现在看来其实也没有什么了。但是对于一个刚入门solr的初学者,我想讲讲关于solr1.3的 solrj( sorlr J 目前使用二进制的格式作为默认的格式。对于solr1.2的用户通过显示的设置才能使用XML格式。)!
先上一个例子:
Java代码
- public static final String SOLR_URL = "http://localhost/solr/core0";
- public static void commit() {
- Date date = new Date();
- SolrServer solr = null;
- try {
- solr = new CommonsHttpSolrServer(SOLR_URL);
- } catch (MalformedURLException e1) {
- e1.printStackTrace();
- }
- for (int i = 0; i < 10000; i++) {
- SolrInputDocument sid = new SolrInputDocument();
- sid.addField("id", i);
- sid.addField("name", "struts+hibernate+spring 开发大全" + i);
- sid.addField("summary", "三种框架的综合应用" + i);
- sid.addField("author", "李良杰" + i);
- sid.addField("date", new Date());
- sid.addField("content", "高级应用类书籍" + i);
- sid.addField("keywords", "SSH" + i);
- try {
- solr.add(sid);
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (SolrServerException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- System.out.println(i);
- if (i == 999)
- System.out.println((new Date().getTime() - date.getTime()) / 60000 + "分钟");
- }
- try {
- solr.commit();
- } catch (SolrServerException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
public static final String SOLR_URL = "http://localhost/solr/core0";
public static void commit() {
Date date = new Date();
SolrServer solr = null;
try {
solr = new CommonsHttpSolrServer(SOLR_URL);
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
for (int i = 0; i < 10000; i++) {
SolrInputDocument sid = new SolrInputDocument();
sid.addField("id", i);
sid.addField("name", "struts+hibernate+spring 开发大全" + i);
sid.addField("summary", "三种框架的综合应用" + i);
sid.addField("author", "李良杰" + i);
sid.addField("date", new Date());
sid.addField("content", "高级应用类书籍" + i);
sid.addField("keywords", "SSH" + i);
try {
solr.add(sid);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(i);
if (i == 999)
System.out.println((new Date().getTime() - date.getTime()) / 60000 + "分钟");
}
try {
solr.commit();
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
上面这段代码的意思是:利用for提交10000个document,并打印提交10000所需的时间。
1》CommonsHttpSolrServer 使用HTTPClient 和solr服务器进行通信。
2》CommonsHttpSorlrServer 允许设置链接属性。
Java代码
- server.setSoTimeout(1000); // socket read timeout
- server.setConnectionTimeout(100);
- server.setDefaultMaxConnectionsPerHost(100);
- server.setMaxTotalConnections(100);
- server.setFollowRedirects(false); // defaults to false
- // allowCompression defaults to false.
- // Server side must support gzip or deflate for this to have any effect.
- server.setAllowCompression(true);
- server.setMaxRetries(1); // defaults to 0. > 1 not recommended.
server.setSoTimeout(1000); // socket read timeout
server.setConnectionTimeout(100);
server.setDefaultMaxConnectionsPerHost(100);
server.setMaxTotalConnections(100);
server.setFollowRedirects(false); // defaults to false
// allowCompression defaults to false.
// Server side must support gzip or deflate for this to have any effect.
server.setAllowCompression(true);
server.setMaxRetries(1); // defaults to 0. > 1 not recommended.
3》实现SolrServer接口的另一个类:EmbeddedSorrServer,它不需要http连接。
4》在构造document的时候,可以一个一个添加到solrServer,也可以构建一个包含document的Collection,将Collection添加到solrServer,然后commit。
5》也可以构造一个跟document匹配的JavaBean进行提交
使用 java 注释创建java bean。@Field ,可以被用在域上,或者是setter方法上。如果一个域的名称跟bean的名称是不一样的,那么在java注释中填写别名,具体的,可以参照下面的域categories
Java代码
- import org.apache.solr.client.solrj.beans.Field;
- public class Item {
- @Field
- String id;
- @Field("cat")
- String[] categories;
- @Field
- List features;
- }
import org.apache.solr.client.solrj.beans.Field;
public class Item {
@Field
String id;
@Field("cat")
String[] categories;
@Field
List features;
}
java注释也可以使用在setter方法上,如下面的例子:
Java代码
- @Field("cat")
- public void setCategory(String[] c){
- this.categories = c;
- }
@Field("cat")
public void setCategory(String[] c){
this.categories = c;
}
这里应该要有一个相对的,get方法(没有加java注释的)来读取属性
Java代码
- Item item = new Item();
- item.id = "one";
- item.categories = new String[] { "aaa", "bbb", "ccc" };
Item item = new Item();
item.id = "one";
item.categories = new String[] { "aaa", "bbb", "ccc" };
添加给solr
Java代码
server.addBean(item);
将多个bean提交给solr
Java代码
- List beans ;
- //add Item objects to the list
- server.addBeans(beans);
List beans ;
//add Item objects to the list
server.addBeans(beans);
注意: 你可以重复使用SolrServer,这样可以提高性能。
6》
Java代码
- public static void update() {
- SolrServer solrServer = null;
- try {
- solrServer = new CommonsHttpSolrServer(SOLR_URL);
- } catch (MalformedURLException e) {
- e.printStackTrace();
- }
- UpdateRequest updateRequest = new UpdateRequest();
- SolrInputDocument sid = new SolrInputDocument();
- sid.addField("id", 100000);
- sid.addField("name", "struts+hibernate+spring 开发大全");
- sid.addField("summary", "三种框架的综合应用");
- sid.addField("author", "李良杰");
- sid.addField("date", new Date());
- sid.addField("content", "高级应用类书籍");
- sid.addField("keywords", "SSH");
- updateRequest.setAction(UpdateRequest.ACTION.COMMIT, false, false);
- updateRequest.add(sid);
- try {
- UpdateResponse updateResponse = updateRequest.process(solrServer);
- System.out.println(updateResponse.getStatus());
- } catch (SolrServerException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
public static void update() {
SolrServer solrServer = null;
try {
solrServer = new CommonsHttpSolrServer(SOLR_URL);
} catch (MalformedURLException e) {
e.printStackTrace();
}
UpdateRequest updateRequest = new UpdateRequest();
SolrInputDocument sid = new SolrInputDocument();
sid.addField("id", 100000);
sid.addField("name", "struts+hibernate+spring 开发大全");
sid.addField("summary", "三种框架的综合应用");
sid.addField("author", "李良杰");
sid.addField("date", new Date());
sid.addField("content", "高级应用类书籍");
sid.addField("keywords", "SSH");
updateRequest.setAction(UpdateRequest.ACTION.COMMIT, false, false);
updateRequest.add(sid);
try {
UpdateResponse updateResponse = updateRequest.process(solrServer);
System.out.println(updateResponse.getStatus());
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
提交一个document,采用更新方式,注意:
Java代码
- updateRequest.setAction(UpdateRequest.ACTION.COMMIT, false, false);
updateRequest.setAction(UpdateRequest.ACTION.COMMIT, false, false);
7》
Java代码
- public static void query() {
- SolrServer solr = null;
- try {
- solr = new CommonsHttpSolrServer(SOLR_URL);
- } catch (MalformedURLException e) {
- e.printStackTrace();
- return;
- }
- // http://localhost:8983/solr/spellCheckCompRH?q=epod&spellcheck=on&spellcheck.build=true
- ModifiableSolrParams params = new ModifiableSolrParams();
- params.set("qt", "/spellCheckCompRH");
- params.set("q", "编程");
- params.set("spellcheck", "on");
- params.set("spellcheck.build", "true");
- QueryResponse response = null;
- try {
- response = solr.query(params);
- } catch (SolrServerException e) {
- e.printStackTrace();
- return;
- }
- System.out.println("response = " + response);
- }
public static void query() {
SolrServer solr = null;
try {
solr = new CommonsHttpSolrServer(SOLR_URL);
} catch (MalformedURLException e) {
e.printStackTrace();
return;
}
// http://localhost:8983/solr/spellCheckCompRH?q=epod&spellcheck=on&spellcheck.build=true
ModifiableSolrParams params = new ModifiableSolrParams();
params.set("qt", "/spellCheckCompRH");
params.set("q", "编程");
params.set("spellcheck", "on");
params.set("spellcheck.build", "true");
QueryResponse response = null;
try {
response = solr.query(params);
} catch (SolrServerException e) {
e.printStackTrace();
return;
}
System.out.println("response = " + response);
}
这是一个查询方法。关键字:“编程”。关于查询的关键字,请参见slor wiki http://wiki.apache.org/solr/QueryParametersIndex,或等待我的博客更新,在后面会有篇文章详细讲这个问题!
8》给solr的索引文件手动进行优化,
Java代码
solr.optimize();
9》solrJ 提供了一组API,来帮助我们创建查询,下面是一个faceted query的例子。
Java代码
Java代码
- SolrServer server = getSolrServer();
- SolrQuery solrQuery = new SolrQuery().setQuery("ipod").setFacet(true).setFacetMinCount(1).setFacetLimit(8). addFacetField("category").addFacetField("inStock");
- QueryResponse rsp = server.query(solrQuery);
SolrServer server = getSolrServer();
SolrQuery solrQuery = new SolrQuery().setQuery("ipod").setFacet(true).setFacetMinCount(1).setFacetLimit(8). addFacetField("category").addFacetField("inStock");
QueryResponse rsp = server.query(solrQuery);
所有的 setter/add 方法都是返回它自己本身的实例,所以就像你所看到的一样,上面的用法是链式的。
- 15:28
- 浏览 (455)
- 评论 (4)
- 分类: solr
- 发布在 lucene爱好者 圈子
- 相关推荐
评论
4 楼 lianj_lee 2009-08-12 引用
290697743 写道
能把第五部分的JAVA文件发上来给我们下载参考吗?,或者发给我
您这一部分一共新建了多少个类啊,我没看懂,而且怎么启动运行,要部署到tomcat上吗?因为我没看到有main方法
我是一个菜鸟!刚开始学solr,一直跟着您这个系列的教程配置solr,现在已经做到:利用SOLR搭建企业搜索平台 之三(配置文件)。越看后面越不懂!
你可以写main程序,也可以写成web程序都是可以的。
第五部分的意思其实就是说可以直接提供一个javabean给solr!
3 楼 290697743 2009-08-11 引用
能把第五部分的JAVA文件发上来给我们下载参考吗?,或者发给我
您这一部分一共新建了多少个类啊,我没看懂,而且怎么启动运行,要部署到tomcat上吗?因为我没看到有main方法
我是一个菜鸟!刚开始学solr,一直跟着您这个系列的教程配置solr,现在已经做到:利用SOLR搭建企业搜索平台 之三(配置文件)。越看后面越不懂!
2 楼 lianj_lee 2009-07-21 引用
imjl 写道
你反复commit干嘛
commit和optimize 仍在循环外,只需要执行一次就够了。
不好意思,手误,手误啊!
很细心!
1 楼 imjl 2009-07-20 引用
你反复commit干嘛
commit和optimize 仍在循环外,只需要执行一次就够了。 |
|