读书人

SOLR筹建企业搜索平台

发布时间: 2012-06-28 15:20:03 作者: rapoo

SOLR搭建企业搜索平台

一、SOLR搭建企业搜索平台--MultiCore?
Solr Multicore 是 solr 1.3 的新特性。其目的一个solr实例,可以有多个搜索应用。?

我们知道你既可以把不同类型的数据放到同一index中,也可以使用分开的多indexes。基于这一点,你只需知道如何使用多 indexes(实际上就是运行Solr的多实例)。尽管如此,为每一个类型添加一个完整的Solr实例会显得太臃肿庞大。Solr1.3引入了Solr core的概念,该方案使用一个Solr实例管理多个indexes,这样就有热点core(hot core)的重读(reloading)与交换(swap,通常是读index与写index交换),那么管理一个 core或index也容易些。每个Solr core由它自己的配置文件和索引数据组成。在多core执行搜索和索引几乎和没有使用core一样。你只是添加core的名字为各自不同的URL。单 core情况下的如下搜索:?
http://localhost:8983/solr/select?q=dave%20matthews?
在多core环境下,你可以通过如下方式访问一个名为mbartists的core:?
http://localhost:8983/solr/core0/select?q=dave%20matthews?
并非在URL中引入core name的参数名值对,而是用不同的context。这样就可以像在单core中执行你的管理任务,搜索,更新操作。?

1、找到solr下载包中的example文件夹,在它的下面有个multicore文件夹,将这个文件夹下面的core0、core1和solr.xml拷贝到 c:\solr-tomcat\solr下面。?
注意:有一个 solr.xml(这只是默认文件,当然也可以指定别的文件),如:?
< ?xml version="1.0" encoding="UTF-8" ?>?
< solr persistent="false">?
<cores adminPath="/admin/cores">?
<core name="core0" instanceDir="core0" />?
<core name="core1" instanceDir="core1" />?
</cores>?
< /solr>?

这个文件是告诉solr应该加载哪些core,<cores>……</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。?
<core name="core0" instanceDir="core0">?
<property name="dataDir" value="/data/core0" />?
< /core>?

一些关键的配置值是:?
1.Persistent="false"指明运行时的任何修改我们不做保存。如拷贝。如果你想保存从启动起的一些改动,那就把 persistent设置为true。如果你的index策略是完成建index到一个纯净的core中然后交换到活动core 那么你绝对应该设为true。?
sharedLib="lib"指明了所有core的jar文件的lib目录。如果你有一个core有自己需要的jar文件,那么你可以把他们置入到core/lib目录。例如:karaoke core 使用 Solr Cell来索引化富文本内容,因此那些用来解析和抽取富文本的jar文件被放到./examples/cores/karaoke/lib/.?

为何使用多core ??
Solr实例支持多core比启用多index要好(do more)。多core同时解决了在生产环境下的一些关键需求:?
1.重建索引?
2.测试配置变更?
3.合并索引?
4.运行时重命名core?
为何多core不是默认的??
多core是1.3版本中才加的,1.4后更成熟。我们强烈建议你使用多core,既是你现在的solr.xml只配置了一个core,虽然会比单个索引稍复杂,但可以带来管理core上的好处。或许一天单个core可能最终RELOAD and STATUS命令,又或许单个core最终会被废禁。多个core会是Solr将来支持大规模分布式索引的关键。因此,以后可以期待更多。?
你可以得到更多的关于Solr的资料:http://wiki.apache.org/solr/CoreAdmin.?

二、 SOLR搭建企业搜索平台--查询参数说明?
在做solr查询的时候,solr提供了很多参数来扩展它自身的强大功能!以下是使用频率最高的一些参数!?
1、常用?
q - 查询字符串,必须的。查询语句(类似SQL) 相关详细的操作还需lucene 的query 语法?
fl - 指定返回那些字段内容,用逗号或空格分隔多个。?
start - 返回第一条记录在完整找到结果中的偏移位置,0开始,一般分页用。?
rows - 指定返回结果最多有多少条记录,配合start来实现分页。?
sort - 排序,格式:sort=<field name>+<desc|asc>[,<field name>+<desc|asc>]… 。示例:(score desc, price asc)表示先 “score” 降序, 再 “price” 升序,默认是相关性降序。?
wt - (writer type)指定输出格式,可以有 xml, json, php, phps, 后面 solr 1.3增加的,要用通知我们,因为默认没有打开。?
fl表示索引显示那些field(*表示所有field, score 是solr 的一个匹配热度)?
q.op 表示q 中 查询语句的 各条件的逻辑操作 AND(与) OR(或)?
hl 是否高亮?
hl.fl 高亮field?
hl.snippets 不太清楚(反正是设置高亮3就可以了)?
hl.simple.pre 高亮前面的格式?
hl.simple.post 高亮后面的格式?
facet 是否启动统计?
facet.field 统计field?
fq - (filter query)过虑查询,作用:在q查询符合结果中同时是fq查询符合的,例如:q=mm&fq=date_time:[20081001 TO 20091031],找关键字mm,并且date_time是20081001到20091031之间的。官方文档:http://wiki.apache.org/solr/CommonQueryParameters#head-6522ef80f22d0e50d2f12ec487758577506d6002?

2、不常用?
q.op - 覆盖schema.xml的defaultOperator(有空格时用"AND"还是用"OR"操作逻辑),一般默认指定?
df - 默认的查询字段,一般默认指定?
qt - (query type)指定那个类型来处理查询请求,一般不用指定,默认是standard。?

3、其它?
indent - 返回的结果是否缩进,默认关闭,用 indent=true|on 开启,一般调试json,php,phps,ruby输出才有必要用这个参数。?
version - 查询语法的版本,建议不使用它,由服务器指定默认值。?

三、 SOLR搭建企业搜索平台--Solr查询语法?

solr的一些查询语法?
1、首先假设我的数据里fields有:name, tel, address 预设的搜寻是name这个字段, 如果要搜寻的数据刚好就是 name 这个字段,就不需要指定搜寻字段名称。?

2、查询规则:?
如欲查询特定字段(非预设字段),请在查询词前加上该字段名称加 “:” (不包含”号) 符号,?
例如: address:北京市海淀区上地软件园 tel:88xxxxx1?
1>. q代表query input?

2>. version代表solr版本(建议不要变动此变量)?

3>. start代表显示结果从哪一笔结果资料开始,预设为0代表第一笔, rows是说要显示几笔数据,预设为10笔?
(因为有时查询结果可能有几百笔,但不需要显示所有结果,所以预设是从第一笔开始到第十笔)?
所以若要显示第10到30笔就改为:?
http: //localhost:8080/solr/select/?indent=on&version=2.2&q=address:北京 市海淀区上地软件园+tel:88xxxxx1&version=2.2&start=10&rows= 20&indent=on?
(indent代表输出的xml要不要缩行.预设为开启 on)?

3、另外,要限定输出结果的内容可用 “fl=” 加上你要的字段名称,如以下这个范例:?
http: //localhost:8080/solr/select/?indent=on&version=2.2&q=text:北京+ OR+text:亿度&start=0&rows=10&fl=name,address,tel?
在fl=之后加上了name,adress,tel?
所以结果会如下:?
<result name=”response” numFound=”1340″ start=”0″>?
< doc>?
< str name=”name”>北京亿度</str>?
< str name=”address”>北京市海淀区上地软件园</str>?
< str name=”tel”>88xxxxxx1</str>?
< /doc>?
< doc>?
< str name=”name”>北京亿度</str>?
< str name=”address”/>?
<str name=”tel”>88xxxxxx1</str>?
< /doc>?
< /result>?

4、查询 name 或 address:直接输入查询词, 如: 亿度?
送出的内容即为:?
name:亿度 AND address:海淀?

5、若要搜寻联集结果,请在词与词间空格或加上大写 “OR” (不包含”号).?
例如: text:海淀 OR text:亿度?
text:海淀 OR 亿度?
或?
海淀 亿度?
或?
name:亿度 OR tel:88xxxxxx1?
或?
name:亿度 tel:88xxxxxx1?
6、若要搜寻交集结果,请在词与词间加上大写 “AND” 或 “+” (不包含”号).?
例如: text:海淀 AND 亿度?
或?
+text:海淀 +text:亿度?
或?
name:亿度 AND tel:88xxxxxx1?
或?
name: ( +亿度 +海淀)?

7、排除查询?
在要排除的词前加上 “-” (不包含”号) 号?
例如: 海淀 -亿度?
搜寻结果不会有包含亿度的词的结果在内?

8、Group 搜寻?
使用 “()” 来包含一个group?
如希望搜寻在店名字段内同时有 “台北”(不包含”号) 及 “火车站”(不包含”号)?

9、增加权重: 如要搜寻 “北京 加油站”(不包含”号) 但因为回传太多笔资料内有 “中华”(不包含”号) 或 “加油站”(不包含”号) 的结果,?
所以想要把有包含 “加油站”(不包含”号)的数据往前排,可使用 “^”(不包含”号)符号在后面加上愈增加的权重数,?
像是 “2″,则可以这样做:?
北京 加油站^2?
会同时搜寻含有北京或加油站的结果,并把加油站这个词加权所以搜寻时会先判断加油站这一个词在搜寻结果中的比重,甚至假设一笔数据内加油站出现过两次以上的就更加会有优先权。?
查询时在查询词后加上 “^” (不包含”号) 再加上权重分数?
例如: 亿度 AND “北京”^2?
或?
亿度^2 OR 北京?

10、Wildcard 搜寻使用 “*” 符号; 如果输入 “中国*银” (不包含”号), 结果会有中国信托商业银行, 中国输出入银行图书阅览室, 中国商银证券?
中国及银之间可夹任何长短字词.?


四、 SOLR搭建企业搜索平台--数据库数据导入到Solr?
详细请参考地址:http://rq2-79.iteye.com/blog/516429?

写程序可以将数据读出100条,如果你的内存够大,可以是1000条甚至更多,然后放入Collection中,批量提交至solr。或者读取数据写入xml文件中,再将该文件提交到solr等等。但是,我们还可以通过配置文件直接读取数据库建立索引。?

1、提供对应数据库的jdbc驱动。?
将jdbc驱动放在TOMCAT_HOME\webapps\solr\WEB-INF\lib目录下。?
2、在C:\solr-tomcat\solr\conf目录下新建db文件夹,在db文件夹中新建db-data-config.xml内容如下:?
<dataConfig>?
<dataSource type="JdbcDataSource" driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@192.168.1.1:1521:数据库名" user="用户名" password="密码"/>?

<document name="messages">?
<entity name="message" transformer="ClobTransformer" query="select * from tb_message">?
<field column="ID" name="id" />?
< field column="TITLE" name="title"/>?
<field column="CONTENT" clob="true" name="content" />?
<field column="SENDTIME" name="sendtime" />?
</entity>?
</document>?
< /dataConfig>?

3、修改C:\solr-tomcat\solr\conf目录下的solrconfig.xml文件。在相应的位置添加如下代码:?
< !-- DataImportHandler -->?
<requestHandler name="/dataimport" driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@192.168.1.1:1521:数据库名" user="用户名" password="密码"/>?

<document name="messages">?
<entity name="message" pk="ID"?
transformer="ClobTransformer"?
query="select * from tb_message"?
deltaQuery="select id from tb_message where to_char(last_modified,'YYYY-MM-DD HH24:MI:SS') > '${dataimporter.last_index_time}'">?
<field column="ID" name="id" />?
<field column="TITLE" name="title" />?
<field column="CONTENT" clob="true" name="content" />?
<field column="SENDTIME" name="sendtime" />?
</entity>?
</document>?
< /dataConfig>?
3、重启tomcat。添加一条记录。?
访问:http://localhost:8089/solr/dataimport?command=delta-import?
再查询一下,是不是可以查询到刚才添加的记录了。?

7、 SOLR搭建企业搜索平台--字段增加权重?
在很多时候,我们可能会需要增加某一个字段的权重,以合理的显示搜索结果。?
例如:有一个schma,有三个字段:chapterId, title, content.?
我们希望某一个关键字如果在title中匹配了,就要优先显示,而在content中匹配了,就放在搜索结果的后面。当然,如果两者同时匹配当然没什么好说的了。看看solr中如何做到吧。?
title:(test1 test2)^4 content:(test1 test2)?
给title字段增加权重,优先匹配?
关于^后面的数字4,经过我测试,最佳值应该是有n个字段就写成n+1,当然希望大家能更好的去测试!?

8、 SOLR搭建企业搜索平台-- Solr分词器、过滤器、分析器?
关于lucene的分析器,分词器,过滤器,请看:http://lianj-lee.iteye.com/blog/501247?

对一个document进行索引时,其中的每个field中的数据都会经历分析(根据上面的一个博客可以知道,分析就是组合分词和过滤),最终将一句话分成单个的单词,去掉句子当中的空白符号,大写转换小写,复数转单数,去掉多余的词,进行同义词代换等等。?
如:This is a blog! this, is, a 会被去除,最后最剩下blog。当然!这个符号也会被去除的。?
这个过程是在索引和查询过程中都会进行的,而且通常两者进行的处理的都是一样的,这样做是为了保证建立的索引和查询的正确匹配。?
分析器(Analyzer)?
分析器是包括两个部分:分词器和过滤器。分词器功能将句子分成单个的词元token,过滤器就是对词元进行过滤。
solr自带了一些分词器,如果你需要使用自定义的分词器,那么就需要修改schema.xml文件。?
schema.xml 文件允许两种方式修改文本被分析的方式,通常只有field类型为 solr.TextField 的field的内容允许定制分析器。?

方法一:使用任何 org.apache.lucene.analysis.Analyzer的子类进行设定。?
<fieldType name="text" isMaxWordLength="false"/>?
……?

</analyzer>?
<analyzer type="query">?
<tokenizer isMaxWordLength="true"/>?
……?
</analyzer>?

需要说明的一点是,Any Analyzer, TokenizerFactory, or TokenFilterFactory 应该用带包名的全类名进行指定,请确保它们位于Solr的classpath 路径下。对于 org.apache.solr.analysis.* 包下的类,仅仅通过solr.*就可以进行指定。?

如果你需要使用自己的分词器和过滤器,你就需要自己写一个 factory ,它必须是 BaseTokenizerFactory(分词器) 或BaseTokenFilterFactory(过滤器)的子类。就像下面一样。?

public class MyFilterFactory extends BaseTokenFilterFactory {?
public TokenStream create(TokenStream input) {?
return new MyFilter(input);?
}?
}?

对于IK3.1.5版本已经完全支持了solr的分词,这样就不用自己来编写了, 而对于中文的切词的话,ik对solr的支持已经很完美了。?

Solr提供了哪些TokenizerFactories??

1. solr.LetterTokenizerFactory?
创建org.apache.lucene.analysis.LetterTokenizer.?
分词举例:?
"I can't" ==> "I", "can", "t",字母切词。?

2. solr.WhitespaceTokenizerFactory?
创建org.apache.lucene.analysis.WhitespaceTokenizer,主要是切除所有空白字符。?

3. solr.LowerCaseTokenizerFactory?
创建org.apache.lucene.analysis.LowerCaseTokenizer?
分词举例:?
"I can't" ==> "i", "can", "t",主要是大写转小写。?

4. solr.StandardTokenizerFactory?
创建org.apache.lucene.analysis.standard.StandardTokenizer?
分词举例: "I.B.M. cat's can't" ==>?
ACRONYM: "I.B.M.", APOSTROPHE:"cat's", APOSTROPHE:"can't"?
说明:该分词器,会自动地给每个分词添加type,以便接下来的对type敏感的过滤器进行处理,目前仅仅只有StandardFilter对Token 的类型是敏感的。?

5. solr.HTMLStripWhitespaceTokenizerFactory?
从结果中除去HTML标签,将结果交给WhitespaceTokenizer处理。?
例子:?
my <a href="www.foo.bar">link</a>?
my link?
< ?xml?><br>hello<!--comment-->?
hello?
hello<script><-- f('<--internal--></script>'); --></script>?
hello?
if a<b then print a;?
if a<b then print a;?
hello <td height=22 nowrap align="left">?
hello?
a<b &#65 Alpha&Omega Ω?
a<b A Alpha&Omega Ω?

6. solr.HTMLStripStandardTokenizerFactory?
从结果中出去HTML标签,将结果交给StandardTokenizer处理。?

7. solr.PatternTokenizerFactory?
说明:按照规则表达式样式对分本进行分词。?
例子:处理对象为,mice; kittens; dogs,他们由分号加上一个或多个的空格分隔。?
<fieldType name="semicolonDelimited" pattern="; *" />?
</analyzer>?
< /fieldType>?


Solr有哪些TokenFilterFactories??

1. solr.StandardFilterFactory?
创建:org.apache.lucene.analysis.standard.StandardFilter.?
移除首字母简写中的点和Token后面的’s。仅仅作用于有类的Token,他们是由StandardTokenizer产生的。?
例:StandardTokenizer+ StandardFilter?
"I.B.M. cat's can't" ==> "IBM", "cat", "can't"?
2. solr.LowerCaseFilterFactory?
创建:org.apache.lucene.analysis.LowerCaseFilter.?
3. solr.TrimFilterFactory【solr1.2】?
创建:org.apache.solr.analysis.TrimFilter?
去掉Token两端的空白符?
例:?
" Kittens! ", "Duck" ==> "Kittens!", "Duck".?
4. solr.StopFilterFactory?
创建:org.apache.lucene.analysis.StopFilter?
去掉如下的通用词,多为虚词。?
"a", "an", "and", "are", "as", "at", "be", "but", "by",?
"for", "if", "in", "into", "is", "it",?
"no", "not", "of", "on", "or", "s", "such",?
"t", "that", "the", "their", "then", "there", "these",?
"they", "this", "to", "was", "will", "with"?
自定义的通用词表的使用可以通过schema.xml文件中的"words"属性来指定,如下。?
<fieldtype name="teststop" words="stopwords.txt" ignoreCase="true"/>?
</analyzer>?
< /fieldtype>?

5. solr.KeepWordFilterFactory【solr1.3】?
创建:org.apache.solr.analysis.KeepWordFilter?
作用与solr.StopFilterFactory相反,保留词的列表也可以通过”word”属性进行指定。?
<fieldtype name="testkeep" words="keepwords.txt" ignoreCase="true"/>?
</analyzer>?
< /fieldtype>?

6. solr.LengthFilterFactory?
创建:solr.LengthFilter?
过滤掉长度在某个范围之外的词。范围设定方式见下面。?
<fieldtype name="lengthfilt" min="2" max="5" />?
</analyzer>?
< /fieldtype>?

7. solr.PorterStemFilterFactory?
创建:org.apache.lucene.analysis.PorterStemFilter?
采用Porter Stemming Algorithm算法去掉单词的后缀,例如将复数形式变成单数形式,第三人称动词变成第一人称,现在分词变成一般现在时的动词。?
8. solr.EnglishPorterFilterFactory?
创建:solr.EnglishPorterFilter?
关于句子主干的处理,其中的"protected"指定不允许修改的词的文件。?
9. solr.SnowballPorterFilterFactory?
关于不同语言的词干处理?
10.solr.WordDelimiterFilterFactory?
关于分隔符的处理。?
11.solr.SynonymFilterFactory?
关于同义词的处理。?
12.solr.RemoveDuplicatesTokenFilterFactory?
避免重复处理。?

五、 SOLR搭建企业搜索平台-- Solr高亮使用?
1、SolrQuery类,此类有方法setHighlight(true),当设置为true时,表示开启了高亮。?
2、SolrQuery类,有方法:?
// 以下给两个字段开启了高亮,分别是name,description,?
query.addHighlightField("name");?
query.addHighlightField("description");?
// 以下两个方法主要是在高亮的关键字前后加上html代码?
query.setHighlightSimplePre("<font color=\"red\">");?
query.setHighlightSimplePost("</font>");?
3、下面是获取高亮的内容:?
Map<String,Map<String,List<String>>> map = response.getHighlighting();?
Map的Key为document的Id,即你在schema.xml中设置的Id,Value为该Id对应的document的值,Value也为一个Map,该Map的Key为fieldName,Value为List<String>,这个List里面的内容就是该文档的高亮字段。?
所以当做逻辑处理的时候,只要按照这个层次,依次把东西给取出来即可,如果取出来的东西为空,则用QueryResponse中的 SolrDocument的getFieldValue(filedName)的值。?
对了,请注意在solrConfig.xml中开启高亮组件,这个可以看看官方wiki或者看solrconfig.xml中注释!?

六、 SOLR搭建企业搜索平台-- Solr的检索运算符?
1. “:” 指定字段查指定值,如返回所有值*:*?
2. “?” 表示单个任意字符的通配?
3. “*” 表示多个任意字符的通配(不能在检索的项开始使用*或者?符号)?
4. “~” 表示模糊检索,如检索拼写类似于”roam”的项这样写:roam~将找到形如foam和roams的单词;roam~0.8,检索返回相似度在0.8以上的记录。?
5. 邻近检索,如检索相隔10个单词的”apache”和”jakarta”,”jakarta apache”~10?
6. “^” 控制相关度检索,如检索jakarta apache,同时希望去让”jakarta”的相关度更加好,那么在其后加上”^”符号和增量值,即jakarta^4 apache?
7. 布尔操作符AND、||?
8. 布尔操作符OR、&&?
9. 布尔操作符NOT、!、- (排除操作符不能单独与项使用构成查询)?
10.“+” 存在操作符,要求符号”+”后的项必须在文档相应的域中存在?
11. ( ) 用于构成子查询?
12. [] 包含范围检索,如检索某时间段记录,包含头尾,date:[200707 TO 200710]?
13. {} 不包含范围检索,如检索某时间段记录,不包含头尾?
date:{200707 TO 200710}?
14. \ 转义操作符,特殊字符包括+ - && || ! ( ) { } [ ] ^ ” ~ * ? : \?
补:?
庖丁分词器?
1. <fieldType name="text" or "this";?
#if value is "this" , using the paoding.dic.home as dicHome if configed!?
#paoding.dic.home.config-fisrt=system-env?

#dictionary home (directory)?
#"classpath:xxx" means dictionary home is in classpath.?
#e.g "classpath:dic" means dictionaries are in "classes/dic" directory or any other classpath directory?
#paoding.dic.home=dic?

#seconds for dic modification detection?
#paoding.dic.detector.interval=60?
paoding.dic.home=C://solr-tomcat//solr//dic?
设置环境变量 paoding.dic.home?
然后在schema.xml中配置FILED的类型是上面定义的Text。

?

转载自:http://blog.163.com/sejin@126/blog/static/827504552011911114058516/

读书人网 >开源软件

热点推荐