读书人

利用SOLR筹建企业搜索平台

发布时间: 2012-07-31 12:33:46 作者: rapoo

利用SOLR搭建企业搜索平台
  3)core
  The <core> 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 <instanceDir>/data . It can take an absolute path or a relative path w.r.t instanceDir .  Solr1.4
  4)property
  The <property> tag accepts two attributes:
  name - The name of the property
  value - The value of the property
  由于E文过于简单,所以就不翻译了!??????????????????????????????????????????????????????????????? 利用SOLR搭建企业搜索平台 之五(solrj)
  比如提交一个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(); 
 } 
}  上面这段代码的意思是:利用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. 
  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<String> features;  
 }   java注释也可以使用在setter方法上,如下面的例子:
  Java代码
@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" }; 

  添加给solr         

  Java代码

server.addBean(item); 

  将多个bean提交给solr

  Java代码

List<Item> 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(); 
 } 
}  提交一个document,采用更新方式,注意:
  Java代码
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); 
}
  这是一个查询方法。关键字:“编程”。关于查询的关键字,请参见slor wiki http://wiki.apache.org/solr/QueryParametersIndex,或等待我的博客更新,在后面会有篇文章详细讲这个问题!
  8》给solr的索引文件手动进行优化,
solr.optimize();
  9》solrJ 提供了一组API,来帮助我们创建查询,下面是一个faceted query的例子。
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 方法都是返回它自己本身的实例,所以就像你所看到的一样,上面的用法是链式的。??????????????????????????????????????????????? 利用SOLR搭建企业搜索平台 之六(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/Comm ... ec487758577506d6002

  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》solr 做索引时报 Lock obtain timed out: SingleInstanceLock: write.lock

  有个频繁做索引的应用,它同时也对外提供搜索服务。大部分是 solr 1.3 的默认配置。solr 做索引,有时候报:

  Xml代码

2009-7-13 9:48:06 org.apache.solr.common.SolrException log 
严重: org.apache.lucene.store.LockObtainFailedException: Lock obtain timed out: SingleInstanceLock: write.lock 
    at org.apache.lucene.store.Lock.obtain(Lock.java:85) 
    at org.apache.lucene.index.IndexWriter.init(IndexWriter.java:1140) 
    at org.apache.lucene.index.IndexWriter.<init>(IndexWriter.java:938) 
    at org.apache.solr.update.SolrIndexWriter.<init>(SolrIndexWriter.java:116) 
...

  是写锁取不到。但重启 solr 又可以正常做,主要是运行时间长了就报这个错了。还是看下配置吧。

  看到 solr 1.3 默认的配置是:

  Xml代码

<indexDefaults>  
  <!-- ... -->  
  <!--  
   This option specifies which Lucene LockFactory implementation to use.  
  
   single = SingleInstanceLockFactory - suggested for a read-only index  
        or when there is no possibility of another process trying  
        to modify the index.  
   native = NativeFSLockFactory  
   simple = SimpleFSLockFactory  
  
   (For backwards compatibility with Solr 1.2, 'simple' is the default  
    if not specified.)  
  -->  
  <lockType>single</lockType>  
</indexDefaults> ??  默认锁是 single ,只读的。solr 1.2 是 simple,把它改回去了,运行了几天,没事。

  2》lucene & solr optimize 索引后结果与平台有点关系

  昨日做索引的程序重构下,测试 optimize 索引(在原有数据基础上提交索引)时,在开发的机器(windows)里总是会有两段索引,要再 optimize 才只是一个索引段,当然不是设置 maxSegments=2。反复运行还是如此,为了说明是否写的程序有问题,就用 solr 自带的 post.sh (或 post.jar)提交 optimize。结果还是有两段,再提交一次optimize 才是一个段。这问题……

  旧的程序运行得很正常,看了下它也没有提交两次优化。然后把新的程序也放到服务器(linux)上运行,结果是只有一个段。

  恩,可以认为是与文件系统有关,optimize 的时候是先新生成一段,然后再删除旧的索引,windows 可能是这样在运行期间与文件关联着删除不了旧的。linux 可能是不用(不打开)文件就可以删除。现只能这样简单解释。

  3》换 solr 里的 lucene 包

  solr 1.3 发布的时候,lucene 2.4还没有正式发布,其的 lucene 是开发版,现在lucene 2.4早已发布,那就换上新的 lucene 吧。

  下载 solr 1.3 http://labs.xiaonei.com/apache-m ... ache-solr-1.3.0.zip 和 lucene 2.4 http://labs.xiaonei.com/apache-m ... va/lucene-2.4.0.zip 到目录如e:/search/,

  把 e:/search/apache-solr-1.3/lib 目录下的 lucene 相关的*.jar删除:

  lucene-analyzers-2.4-dev.jar

  lucene-core-2.4-dev.jar

  lucene-highlighter-2.4-dev.jar

  lucene-memory-2.4-dev.jar

  lucene-queries-2.4-dev.jar

  lucene-snowball-2.4-dev.jar

  lucene-spellchecker-2.4-dev.jar

  从 e:/search/lucene-2.4/(或contrib/)目录下找到对应的放到solr-1.3/lib下

  然后构建 solr,到e:/search/apache-solr-1.3目录,ant dist-war

  4》solr q查询容错性

  当solr接收没q参数(或q参数值为空)请求时,会报错。报错十分讨厌,对开发调试时才比较有用,但实际运行环境报错就不太好了,java异常可能有点性能消耗,那干脆就返回正常的结果好了(只是结果里没有找到的数据)。

  solr 1.3 可以写个组件去做。判断到空的时候,加一个q参数,其值为在索引里没有的数据。这样就可以返回没有数据的结果。

  其实这样实现还是比较麻烦。可以在 solrconfig.xml的requestHandler里加一个默认参数。如q=abcdefghijk。配置如下:

  Xml代码

<requestHandler name="standard" /> 

  定义一个 handler 使用上面的搜索组件:

  Xml代码

<requestHandler name="collapse" height="275" width="550" src="/img/2012/06/24/0928004278.png">0 && image.height<0){if(image.width<=700){this.width=700;this.height=image.height*700/image.width;}}" border=0<


  六.启动TOMCAT,输入地址进行导入,导入分为很多模式:我选用的全部倒入模式。
  http://localhost/solr/dataimport?command=full-import
  结果:
  00C:\solr-tomcat\solr\db\conf\db-data-config.xmlfull-importidle1202009-09-0521:28:08Indexing completed. Added/Updated: 2 documents. Deleted 0documents.2009-09-05 21:28:092009-09-05 21:28:090:0:0.579This responseformat is experimental. It is likely to change in the future.
  七.在去查询你刚才提交的数据,搞定。
  最后在说说这个功能。上面的例子只不过是很简单的一个部分。针对solr的MultiCore,通过配置db-data-config.xml也可以实现,还有多表,或者多表关联等等操作只要在db-data-config.xml配置清楚都可以进行数据的导入。
  在solr1.4中还有更多的扩展功能,这些功能为重建索引提供能很方便的操作。而且,datasource不单单指的是database,可以是xml文件,还可以是来自网络上的等等。??利用SOLR搭建企业搜索平台 之十一(中文分词之IK)

   在经过使用了庖丁以后,这里说说怎么将目前很火很流行的IK集成进SOLR,其实方法真的很简单,比paoding方便不少。这里很感谢IK的作者,蓝山咖啡,很感谢你为中文分词做出的贡献。 作者博客:http://linliangyi2007.javaeye.com
  入正题:
  1》请先去作者博客参看IK下载地址,主要就是一个IKAnalyzer3.1.1Stable.jar。我这里用的是最新版!
  Java代码 package com.yeedoo.slor.tokenizer; 
 
import java.io.Reader; 
 
import org.apache.lucene.analysis.TokenStream; 
import org.apache.solr.analysis.BaseTokenizerFactory; 
import org.wltea.analyzer.lucene.IKAnalyzer; 
 
public class ChineseTokenizerFactory extends BaseTokenizerFactory { 
 
 @Override 
 public TokenStream create(Reader reader) { 
 return new IKAnalyzer().tokenStream("text", reader); 
 } 
 
}
  从代码就可以看得出来真的很方便!将它打包放入solr.war中同时还有IK的jar包。如果你不想打包,请去附件下载已经打好的包。
  2》配置文件
  Xml代码 <fieldType name="text" height="431" width="700" src="/img/2012/06/24/0928004279.png">

读书人网 >开源软件

热点推荐