1. 程式人生 > >Solr 查詢,索引

Solr 查詢,索引

環境
Solr: apache-solr-3.6.2
Tomcat:Tomcat 6.0
JDK: jdk1.6
pc : windows7


Solr的安裝和配置

首先 安裝 jdk  --> 然後 tomcat  

下載solr 下載地址:http://apache.etoak.com/lucene/solr/1.4.1/ 詳情請見:http://wiki.apache.org/solr/Solr1.4

解壓縮
solr 到   E:\solr
tomcat:   C:\Tomcat 6.0


Solr 在jetty 中啟動

一般下載solr都自帶 jetty serlvet 伺服器,可以直接使用啟動.

cd E:\solr\apache-solr-3.6.2\example

java -jar start.jar   //這樣就可以啟動了

http://localhost:8080/solr/admin   只要看到 solr的控制檯頁面 solr 就成功 啟動了


有關 jetyy 的 埠配置  在  E:\solr\apache-solr-3.6.2\example\etc  這個目錄下的 jetty.xml  可以修改埠 



Solr 在  tomcat中的啟動

//1.修改tomcat 的編碼格式   
cd   C:\Tomcat 6.0\conf\server.xml
加上   URIEncoding="UTF-8"
 <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" URIEncoding="UTF-8" />

//2.拷貝 E:\solr\apache-solr-3.6.2\example\webapps\solr.war 到 C:\Tomcat 6.0\webapps

//3.配置solr.home
在  C:\Tomcat 6.0\conf\Catalina\localhost 新建 solr.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="C:\Tomcat 6.0\webapps\solr.war" debug="0" crossContext="true">
	<Environment name="solr/home" type="java.lang.String" value="E:\solr\apache-solr-3.6.2\example\solr" override="true"/>
</Context>

//3.5配置 solr.home 的 方法二
修改 solr.war 中的  web.xml   新增 如下配置 也可以(一般web.xml中已經包含了只需取消註釋就可以了)
<env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>E:\solr\apache-solr-3.6.2\example\solr</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
</env-entry>

然後重新打包 
java -cvf  solr.war  *.*  將 解壓後的sole.war  重新打包部署

//4.啟動 tomcat就 然後 訪問 http://localhost:8080/solr/admin

//5 進入控制檯   預設使用  "*:*" 查詢所有 文件   這個 可以在  E:\solr\apache-solr-3.6.2\example\solr\conf\solrconfig.xml 中 修改
 <defaultQuery>*:*</defaultQuery>  一般 不建議修改 



使用 post.jar 提交 doc  到 solr
//使用  solr自帶的各種檔案 建立索引
solr自帶的 所有例項文件  在  E:\solr\apache-solr-3.6.2\example\exampledocs

可以看出  solr 可以使用個json, csb .xml 各種各樣的文件 建立索引 

還有一個 重要的post .jar  

cd E:\solr\apache-solr-3.6.2\example\exampledocs
java   -jar -Durl=http://localhost:8080/solr/update  -Dcommit=yes post.jar  *.xml
將所有的  xml檔案 加入 solr中 

然後回到 控制檯  使用 "*:*" 就可以執行各種查詢了.


solr 的兩個主要配置檔案

E:\solr\apache-solr-3.6.2\example\solr\conf

schema.xml : 是索引的schema ,包含了域的定義 和相關 analyzer鏈  還有solr中支援的一些 基本型別 以及  對應我們 javabean 中的一些  field  fieldtype  等 

solrconfig.xml: 該檔案是 solr的主配置檔案,



mmseg4j中文分詞的配置
1) 下載分詞器:http://code.google.com/p/mmseg4j/
2) 下載詞庫:http://code.google.com/p/mmseg4j/downloads/detail?name=data.zip&can=2&q=

3) 加入 :mmseg4j 目錄下的 dist 中的jar  到  C:\Tomcat 6.0\webapps\solr\web-inf\lib\ 

4) 在E:\solr\apache-solr-3.6.2\example\solr\ 下 建立dic 目錄使用者存放分詞目錄 容納然後見下載 mmseg4j的分詞庫 中的  chars.dic units.dic words.dic words-my.dic 放入到 dic 目錄

5) 修改E:\solr\apache-solr-3.6.2\example\solr\conf\ schema.xml 加入 mmseg4j的配置 
 使用者 替換  solr中預設的 "text" "fieldtype" 
在 <typs> 中新增  需要注意的是 dicPath 的值 是我們剛剛建立的 dic 目錄

<fieldType name="textComplex" class="solr.TextField" positionIncrementGap="100" >  
		<analyzer>  
			<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="dic"/>  
			<filter class="solr.LowerCaseFilterFactory"/>  
		</analyzer>  
	</fieldType>  
	<fieldType name="textMaxWord" class="solr.TextField" positionIncrementGap="100" >  
		<analyzer>  
			<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="max-word" dicPath="dic"/>  
			<filter class="solr.LowerCaseFilterFactory"/>  
		</analyzer>  
	</fieldType>  

	<fieldType name="textSimple" class="solr.TextField" positionIncrementGap="100" >  
		<analyzer>  
			<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" dicPath="dic"/>  
			<filter class="solr.LowerCaseFilterFactory"/>  
		</analyzer>  
	</fieldType>  


然後在 <fields>中 新增  

<!-- mmseg4j fields -->
	<field name="simple" type="textSimple" indexed="true" stored="true" multiValued="true"/>  
	<field name="complex" type="textComplex" indexed="true" stored="true" multiValued="true"/>  
	<field name="text" type="textMaxWord" indexed="true" stored="true" multiValued="true"/> 

然後在</schema> 裡面新增  

<!-- mmseg4j coypField-->
<copyField source="text" dest="simple" />  
<copyField source="text" dest="complex" /> 

配置好後 啟動服務  

訪問
http://192.168.10.85:18080/solr/admin/analysis.jsp 就可以看到 mmseg4j的分詞效果,在 filed拉下中選擇  name 也就是我們配置的 filed 型別
 輸入一句話  ,然後點選  analyzer 就可以看到效果了

如果要是外接程式也能夠利用 這個 分詞來更新索引 需要新增這個配置 
在 solrconfig.xml: 

<requesthandler name="/mmseg4j" class="com.chenlb.mmseg4j.solr.MMseg4jHandler"><lst name="defaults">
  <str name="dicPath">
   <str name="dicPath"> dic </str>
  </str>
 </lst> 
</requesthandler>


IK Analyzer 中文分詞 的使用個
和上面的步驟類似
2.1 下載地址 

GoogleCode 開源專案 :http://code.google.com/p/ik-analyzer/ 

GoogleCode  下載:http://code.google.com/p/ik-analyzer/downloads/list 

加入 IKAnalyzer的jar 到 web-inf/lib 下

然後 修改  schema.xml檔案 加入 fieldtype

<!-- IK Analyzer types-->
     <fieldType name="text_ik" class="solr.TextField">
		<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
		<analyzer type="index">
		     <tokenizer class="org.wltea.analyzer.solr.IKTokenizerFactory" isMaxWordLength="false"/>
			 <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
			 <filtr class="solr.WordDelimiterFilterFactory" 
			  generateWordParts="1"
			  generateNumberPats="1"
			  catenateWords="1"
			  catenateNumbers="1"
			  catenateAll="0"
			  splitOnCaseChange="1"/>
			 <filter class="solr.LowerCaseFilterFactory"/>
			 <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/>
			 <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
		</analyzer>

		<analyzer type="query">
		   <tokenizer class="org.wltea.analyzer.solr.IKTokenizerFactory"
		   isMaxWordLength="false"/>
			<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
			 <filtr class="solr.WordDelimiterFilterFactory" 
			  generateWordParts="1"
			  generateNumberPats="1"
			  catenateWords="1"
			  catenateNumbers="1"
			  catenateAll="0"
			  splitOnCaseChange="1"/>
			 <filter class="solr.LowerCaseFilterFactory"/>
			 <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/>
			 <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
		</analyzer>
	 </fieldType>


加入 field
	<!--IK Analyzer filed-->
   <field name="text" type="text_ik" indexed="true" stored="false" multiValued="true" required="true"/>


然後在c:\tomcat6.0\webapps\solr\WEB-INF\classes 中加入 IKAnalyzer.cfg.xml 和 擴充套件字典 和 停止 字典 檔案 

然後訪問 
http://localhost:8080/solr/admin/analysis.jsp
操作類是於 mmseg4j 



使用DataImportHandler 的從不同的檔案中對資料進行 索引的新增

1.不用說首先加入 jar 到  web-inf\lib中啦 

2.然後在  E:\solr\apache-solr-3.6.2\example\solr\conf\db\data-config.xml 中加入 與資料的連線配置和 field對映 
<dataConfig>
    <dataSource type="JdbcDataSource" name="ds-1" driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@192.168.1.242:1521:ora11g" user="bjdata"  password="bjdata"/>
	<!--
	<dataSource type="JdbcDataSource" name="ds-1" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://db1-host/dbname" user="db_username" password="db_password"/>  <dataSource type="JdbcDataSource" name="ds-2" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://db2-host/dbname" user="db_username" password="db_password"/>
	
	
	-->
    <document>
        <entity dataSource="ds-1" name="bi_baoliao" 
		query="select id,userid,username,prodname,tags,createtime from bi_baoliao"
        deltaQuery="select id from bi_baoliao where createtime > '${dataimporter.last_index_time}'">

			<field column="Id" name="id" />
			<field column="USERID"  name="userid" />
			<field column="USERNAME"  name="username"/>
			<field column="PRODNAME"  name="prodname"/>
			<field column="TAGS"  name="tags"/>
			<field column="CREATETIME"  name="createtime" dateTimeFormat="yyyy-MM-dd HH:mm:ss"/>
			
        </entity>
    </document>
</dataConfig>


然後 在 solrconfig.xml中新增 

  <!--DataImportHandler -->
	<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
    <lst name="defaults">
      <str name="config">./db/data-config.xml</str>
    </lst>
  </requestHandler>


然後啟動 服務  
然後使用 http請求 建立 全量索引   增量索引
http://localhost:8080/solr/dataimport?command=full-import 全量索引 

對應 data-config.xml中的 entity 中  query sql語句  

http://localhost:8080/solr/dataimport?command=delta-import  增量索引
對應 data-config.xml中的 entity 中  deltaQuery   sql語句  

還有一些 command 的引數
full-import : "完全匯入"
clean : (default 'true'). 決定在建立索引之前,刪除以前的索引。
commit: (default 'true'). 決定這個操作之後是否要commit
optimize: (default 'true'). 決定這個操作之後是否要優化。
debug : (default false). 工作在debug模式下。
delta-import : 當遇到一些增量的輸入,
status : 想要知道命令執行的狀態 ,
reload-config : 如果data-config.xml已經改變,你不希望重啟solr,而要重新載入配置時,執行一下的命令http://:/solr/dataimport?command=reload-config
abort : 你可以通過訪問 url http://:/solr/dataimport?command=abort 來終止一個在執行的操作

還可以在 這個配置檔案中 配置  json   xml  rss 不同型別資料來源的匯入  

更多請看下面有關 DIH
http://wiki.apache.org/solr/DataImportHandler

solr的查詢 貼上一個文章來 看
http://www.doc88.com/p-008848668417.html
http://wiki.apache.org/solr/CoreQueryParameters

常用
q - 查詢字串,必須的。
fl - 指定返回那些欄位內容,用逗號或空格分隔多個。
start - 返回第一條記錄在完整找到結果中的偏移位置,0開始,一般分頁用。
rows - 指定返回結果最多有多少條記錄,配合start來實現分頁。
sort - 排序,格式:sort=<field name>+<desc|asc>[,<field name>+<desc|asc>]… 。示例:(inStock desc, price asc)表示先 “inStock” 降序, 再 “price” 升序,預設是相關性降序。
wt - (writer type)指定輸出格式,可以有 xml, json, php, phps, 後面 solr 1.3增加的,要用通知我們,因為預設沒有開啟。
fq - (filter query)過慮查詢,作用:在q查詢符合結果中同時是fq查詢符合的,例如:q=mm&fq=date_time:[20081001 TO 20091031],找關鍵字mm,並且date_time是20081001到20091031之間的。官方文件:http://wiki.apache.org/solr/CommonQueryParameters
不常用
q.op - 覆蓋schema.xml的defaultOperator(有空格時用"AND"還是用"OR"操作邏輯),一般預設指定
df - 預設的查詢欄位,一般預設指定
qt - (query type)指定那個型別來處理查詢請求,一般不用指定,預設是standard。
其它
indent - 返回的結果是否縮排,預設關閉,用 indent=true|on 開啟,一般除錯json,php,phps,ruby輸出才有必要用這個引數。
version - 查詢語法的版本,建議不使用它,由伺服器指定預設值。
[Solr的檢索運算子]
 “:” 指定欄位查指定值,如返回所有值*:*²
 “?”²表示單個任意字元的通配
 “*” 表示多個任意字元的通配(不能在檢索的項開始使用*或者?符號)²
 “~”²表示模糊檢索,如檢索拼寫類似於”roam”的項這樣寫:roam~將找到形如foam和roams的單詞;roam~0.8,檢索返回相似度在0.8以上的記錄。
²鄰近檢索,如檢索相隔10個單詞的”apache”和”jakarta”,”jakarta apache”~10
 “^”²控制相關度檢索,如檢索jakarta apache,同時希望去讓”jakarta”的相關度更加好,那麼在其後加上”^”符號和增量值,即jakarta^4 apache
 布林操作符AND、||²
 布林操作符OR、²&&
 布林操作符NOT、!、-²(排除操作符不能單獨與項使用構成查詢)
 “+” 存在操作符,要求符號”+”後的項必須在文件相應的域中存在²
 ( ) 用於構成子查詢²
² [] 包含範圍檢索,如檢索某時間段記錄,包含頭尾,date:[200707 TO 200710]
 {}²不包含範圍檢索,如檢索某時間段記錄,不包含頭尾
date:{200707 TO 200710}
 " 轉義操作符,特殊字元包括+ -² && || ! ( ) { } [ ] ^ ” ~ * ? : "


Solr 刪除全部索引:http://localhost:8080/solr/update/?stream.body=<delete><query>*:*</query></delete>&stream.contentType=text/xml;charset=utf-8&commit=true


Solr 查詢索引記錄:http://localhost:8080/solr/select/?q=%E5%85%A8%E6%96%87&version=2.2&start=0&rows=10&indent=on

日期查詢
Approvetime:[NOW/DAY-1DAY TO NOW/DAY]
Approvetime:[NOW-1DAY TO NOW]
Approvetime:[NOW-7DAY TO NOW]

Approvetime:[NOW-1MONTH TO NOW]

createdate:[1995-12-31\T23:59:59.999\Z TO 2007-03-06\T00:00:00\Z]


我想到這裡你已經夠用了 哈哈

solrj

//加入 solr中的jar  在 下載的 solr中 dist中有個  solrj  
apache-solr-core-3.6.2.jar
apache-solr-dataimporthandler-3.6.2.jar
apache-solr-solrj-3.6.2.jar
bjdata-common.jar
bjdata-util.jar
commons-codec-1.6.jar
commons-httpclient-3.1.jar
commons-io-2.1.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
IKAnalyzer2012_u6.jar
IKAnalyzer3.2.8.jar
jcl-over-slf4j-1.6.1.jar
log4j-1.2.14.jar
ojdbc6.jar
pinyin4j-2.5.0.jar
poi-3.7-20101029.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.7.5.jar
wstx-asl-3.2.7.jar

//各種測試案例

package com.sh.test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.xml.registry.infomodel.User;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.SolrRequest.METHOD;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.TermsResponse;
import org.apache.solr.client.solrj.response.TermsResponse.Term;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.SolrInputField;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.sh.baoliao.model.BiSearchBaoLiao;

public class ServerTest {

	private SolrServer server;  //有 HttpSolrServer EmbeddedSolrServer 兩個
	
	private static final String DEFAULT_URL="http://localhost:8983/solr";
	private HttpSolrServer solrServer;  //CommonsHttpSolrServer solrServer; 過時
	
	private EmbeddedSolrServer esolrServer;
	@Before
	public void init(){
		try {
			server =new HttpSolrServer(DEFAULT_URL);
			
			solrServer=new HttpSolrServer(DEFAULT_URL);
			
			//Server的有關配置選項引數 
			solrServer.setSoTimeout(1000); //socket read timeout
			solrServer.setConnectionTimeout(100);
			solrServer.setDefaultMaxConnectionsPerHost(100);
			solrServer.setMaxTotalConnections(100);
			solrServer.setFollowRedirects(false); // defaults to false 
			solrServer.setAllowCompression(true); 
			//solr 1.2 需要顯示設定返回的型別
			//solrServer.setParser(new XMLResponseParser());
			//solrServer.setRequestWriter(new BinaryRequestWriter());
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@After
	public void destory(){
		server=null;
		solrServer=null;
		System.runFinalization();
		System.gc();
	}
	
	public final void fail(Object o){
		System.out.println(o);
	}
	
	/**
	 * 測試連線建立serve物件成功
	 */
	@Test  
	public void test() {
		//測試前先刪除所有索引
		try {
			server.deleteByQuery( "*:*" );
		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		fail(server);
		fail(solrServer);
	}
	
	/**
	 * 根據query引數查詢索引
	 * @param query
	 */
	@Test
	public void query(String query){
		if(query==null)
			query="id:373";
		
		SolrParams params=new SolrQuery(query);
		try {
			QueryResponse response=server.query(params);
			
			SolrDocumentList list=response.getResults();
			
			for (int i = 0; i < list.size(); i++) {
				fail(list.get(i));
			}
		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//4、 利用SolrJ完成Index Document的新增操作
	@Test
	public void addDoc() {
	    //建立doc文件
	    SolrInputDocument doc = new SolrInputDocument();
	    doc.addField("id", 1);
	    doc.addField("name", "Solr Input Document");
	    doc.addField("manu", "this is SolrInputDocument content");
	    
	    try {
	        //新增一個doc文件
	        UpdateResponse response = server.add(doc);
	        fail(server.commit());//commit後才儲存到索引庫
	        fail(response);
	        fail("query time:" + response.getQTime());
	        fail("Elapsed Time:" + response.getElapsedTime());
	        fail("status:" + response.getStatus());
	    } catch (SolrServerException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	    query("name:solr");
	}
	
	//5、 利用SolrJ新增多個Document,即新增文件集合
	/**
	 * <b>function:</b> 新增docs文件集合
	 * @author hoojo
	 * @createDate 2011-10-21 上午09:55:01
	 */
	@Test
	public void addDocs() {
	    Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
	    SolrInputDocument doc = new SolrInputDocument();
	    doc.addField("id", 2);
	    doc.addField("name", "Solr Input Documents 1");
	    doc.addField("manu", "this is SolrInputDocuments 1 content");
	    
	    docs.add(doc);
	    
	    doc = new SolrInputDocument();
	    doc.addField("id", 3);
	    doc.addField("name", "Solr Input Documents 2");
	    doc.addField("manu", "this is SolrInputDocuments 3 content");
	    
	    docs.add(doc);
	    
	    try {
	        //add docs
	        UpdateResponse response = server.add(docs);
	        //commit後才儲存到索引庫
	        fail(server.commit());
	        fail(response);
	    } catch (SolrServerException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	    query("solr");
	}
	
	//7、 新增Bean集合
	@Test
	public void addBean() {
	    //Index需要新增相關的Annotation註解,便於告訴solr哪些屬性參與到index中
	    BiSearchBaoLiao index = new BiSearchBaoLiao();
	    index.setId(4l);
	    index.setUserid(21l);
	    index.setUsername("add bean index");
	    index.setProdname("新增Index Bean到索引庫");
	    
	    try {
	        //新增Index Bean到索引庫
	        UpdateResponse response = server.addBean(index);
	        fail(server.commit());//commit後才儲存到索引庫
	        fail(response);
	    } catch (SolrServerException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	    queryAll();
	}
	
	//8、 刪除索引Document

	/**
	 * <b>function:</b> 刪除索引操作
	 * @author hoojo
	 * @createDate 2011-10-21 上午10:04:28
	 */
	@Test
	public void remove() {
	    try {
	        //刪除id為1的索引
	        server.deleteById("1");
	        server.commit();
	        query("id:1");
	        
	        //根據id集合,刪除多個索引
	        List<String> ids = new ArrayList<String>();
	        ids.add("2");
	        ids.add("3");
	        server.deleteById(ids);
	        server.commit(true, true);
	        query("id:3 id:2");
	        
	        //刪除查詢到的索引資訊
	        server.deleteByQuery("id:4 id:6");
	        server.commit(true, true);
	        queryAll();
	        
	    } catch (SolrServerException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	}
	
	//9、 查詢索引
	@Test
	public void queryAll() {
	    ModifiableSolrParams params = new ModifiableSolrParams();
	    // 查詢關鍵詞,*:*代表所有屬性、所有值,即所有index
	    params.set("q", "*:*");
	    // 分頁,start=0就是從0開始,,rows=5當前返回5條記錄,第二頁就是變化start這個值為5就可以了。
	    params.set("start", 0);
	    params.set("rows", Integer.MAX_VALUE);
	    
	    // 排序,,如果按照id 排序,,那麼將score desc 改成 id desc(or asc)
	    params.set("sort", "score desc");
	 
	    // 返回資訊 * 為全部 這裡是全部加上score,如果不加下面就不能使用score
	    params.set("fl", "*,score");
	    
	    try {
	        QueryResponse response = server.query(params);
	        
	        SolrDocumentList list = response.getResults();
	        for (int i = 0; i < list.size(); i++) {
	            fail(list.get(i));
	        }
	    } catch (SolrServerException e) {
	        e.printStackTrace();
	    }
	}
	
	
	//10、 其他和Server有關方法
	/**
	 * <b>function:</b> 其他server相關方法測試
	 * @author hoojo
	 * @createDate 2011-10-21 上午10:02:03
	 */
	@Test
	public void otherMethod() {
	    fail(server.getBinder());
	    try {
	        fail(server.optimize());//合併索引檔案,可以優化索引、提供效能,但需要一定的時間
	        fail(server.ping());//ping伺服器是否連線成功
	        
	        BiSearchBaoLiao index = new BiSearchBaoLiao();
		    index.setId(4l);
		    index.setUserid(21l);
		    index.setUsername("add bean index");
		    index.setProdname("新增Index Bean到索引庫");
	        
	        UpdateResponse response = server.addBean(index);
	        fail("response: " + response);
	        
	        queryAll();
	        //回滾掉之前的操作,rollback addBean operation
	        fail("rollback: " + server.rollback());
	        //提交操作,提交後無法回滾之前操作;發現addBean沒有成功新增索引
	        fail("commit: " + server.commit());
	        queryAll();
	    } catch (SolrServerException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	}

	//11、 文件查詢

	/**
	 * <b>function:</b> query 基本用法測試
	 * @author hoojo
	 * @createDate 2011-10-20 下午04:44:28
	 */
	@Test
	public void queryCase() {
	    //AND 並且
	    SolrQuery params = new SolrQuery("name:apple AND manu:inc");
	    
	    //OR 或者
	    params.setQuery("name:apple OR manu:apache");
	    //空格 等同於 OR
	    params.setQuery("name:server manu:dell");
	    
	    //params.setQuery("name:solr - manu:inc");
	    //params.setQuery("name:server + manu:dell");
	    
	    //查詢name包含solr apple
	    params.setQuery("name:solr,apple");
	    //manu不包含inc
	    params.setQuery("name:solr,apple NOT manu:inc");
	    
	    //50 <= price <= 200
	    params.setQuery("price:[50 TO 200]");
	    params.setQuery("popularity:[5 TO 6]");
	    //params.setQuery("price:[50 TO 200] - popularity:[5 TO 6]");
	    //params.setQuery("price:[50 TO 200] + popularity:[5 TO 6]");
	    
	    //50 <= price <= 200 AND 5 <= popularity <= 6
	    params.setQuery("price:[50 TO 200] AND popularity:[5 TO 6]");
	    params.setQuery("price:[50 TO 200] OR popularity:[5 TO 6]");
	    
	    //過濾器查詢,可以提高效能 filter 類似多個條件組合,如and
	    //params.addFilterQuery("id:VA902B");
	    //params.addFilterQuery("price:[50 TO 200]");
	    //params.addFilterQuery("popularity:[* TO 5]");
	    //params.addFilterQuery("weight:*");
	    //0 < popularity < 6  沒有等於
	    //params.addFilterQuery("popularity:{0 TO 6}");
	    
	    //排序
	    params.addSortField("id", ORDER.asc);
	    
	    //分頁:start開始頁,rows每頁顯示記錄條數
	    //params.add("start", "0");
	    //params.add("rows", "200");
	    //params.setStart(0);
	    //params.setRows(200);
	    
	    //設定高亮
	    params.setHighlight(true); // 開啟高亮元件
	    params.addHighlightField("name");// 高亮欄位
	    params.setHighlightSimplePre("<font color='red'>");//標記,高亮關鍵字字首
	    params.setHighlightSimplePost("</font>");//字尾
	    params.setHighlightSnippets(1);//結果分片數,預設為1
	    params.setHighlightFragsize(1000);//每個分片的最大長度,預設為100
	 
	    //分片資訊
	    params.setFacet(true)
	        .setFacetMinCount(1)
	        .setFacetLimit(5)//段
	        .addFacetField("name")//分片欄位
	        .addFacetField("inStock"); 
	    
	    //params.setQueryType("");
	    
	    try {
	        QueryResponse response = server.query(params);
	        
	        /*List<Index> indexs = response.getBeans(Index.class);
	        for (int i = 0; i < indexs.size(); i++) {
	            fail(indexs.get(i));
	        }*/
	        
	        //輸出查詢結果集
	        SolrDocumentList list = response.getResults();
	        fail("query result nums: " + list.getNumFound());
	        for (int i = 0; i < list.size(); i++) {
	            fail(list.get(i));
	        }
	        
	        //輸出分片資訊
	        List<FacetField> facets = response.getFacetFields();
	        for (FacetField facet : facets) {
	            fail(facet);
	            List<Count> facetCounts = facet.getValues();
	            for (FacetField.Count count : facetCounts) {
	                System.out.println(count.getName() + ": " + count.getCount());
	            }
	        }
	    } catch (SolrServerException e) {
	        e.printStackTrace();
	    } 
	}
	
	//12、 分片查詢、統計

	/**
	 * <b>function:</b> 分片查詢, 可以統計關鍵字及出現的次數、或是做自動補全提示
	 * @author hoojo
	 * @createDate 2011-10-20 下午04:54:25
	 */
	@Test
	public void facetQueryCase() {
	    SolrQuery params = new SolrQuery("*:*");
	    
	    //排序
	    params.addSortField("id", ORDER.asc);
	    
	    params.setStart(0);
	    params.setRows(200);
	 
	    //Facet為solr中的層次分類查詢
	    //分片資訊
	    params.setFacet(true)
	        .setQuery("*:*")
	        .setFacetMinCount(1)
	        .setFacetLimit(5)//段
	        //.setFacetPrefix("electronics", "cat")
	        .setFacetPrefix("cor")//查詢manu、name中關鍵字字首是cor的
	        .addFacetField("manu")
	        .addFacetField("name");//分片欄位
	 
	    try {
	        QueryResponse response = server.query(params);
	        
	        //輸出查詢結果集
	        SolrDocumentList list = response.getResults();
	        fail("Query result nums: " + list.getNumFound());
	        
	        for (int i = 0; i < list.size(); i++) {
	            fail(list.get(i));
	        }
	        
	        fail("All facet filed result: ");
	        //輸出分片資訊
	        List<FacetField> facets = response.getFacetFields();
	        for (FacetField facet : facets) {
	            fail(facet);
	            List<Count> facetCounts = facet.getValues();
	            for (FacetField.Count count : facetCounts) {
	                //關鍵字 - 出現次數
	                fail(count.getName() + ": " + count.getCount());
	            }
	        }
	        
	        fail("Search facet [name] filed result: ");
	        //輸出分片資訊
	        FacetField facetField = response.getFacetField("name");
	        List<Count> facetFields = facetField.getValues();
	        for (Count count : facetFields) {
	            //關鍵字 - 出現次數
	            fail(count.getName() + ": " + count.getCount());
	        }
	    } catch (SolrServerException e) {
	        e.printStackTrace();
	    } 
	}
	//分片查詢在某些統計關鍵字的時候還是很有用的,可以統計關鍵字出現的次數,可以通過統計的關鍵字來搜尋相關文件的資訊。
	
	

    /**
     * <b>function:</b> 建立SolrInputDocument
     * @author hoojo
     * @createDate 2011-10-21 下午03:38:20
     */
    @Test
    public void createDoc() {
        SolrInputDocument doc = new SolrInputDocument();
        doc.addField("id", System.currentTimeMillis());
        doc.addField("name", "SolrInputDocument");
        doc.addField("age", 22, 2.0f);
        
        doc.addField("like", new String[] { "music", "book", "sport" });
        
        doc.put("address", new SolrInputField("guangzhou"));
        
        doc.setField("sex", "man");
        doc.setField("remark", "china people", 2.0f);
        
        fail(doc);
    }
    
    /**
     * <b>function:</b> 利用DocumentObjectBinder物件將SolrInputDocument 和 User物件相互轉換
     * @author hoojo
     * @createDate 2011-10-21 下午03:38:40
     */
    @Test
    public void docAndBean4Binder() {
        SolrDocument doc = new SolrDocument();
        doc.addField("id", 456);
        doc.addField("name", "SolrInputDocument");
        
        doc.addField("likes", new String[] { "music", "book", "sport" });
        
        doc.put("address", "guangzhou");
        
        doc.setField("sex", "man");
        doc.setField("remark", "china people");
        
        DocumentObjectBinder binder = new DocumentObjectBinder();
        
        BiSearchBaoLiao user = new BiSearchBaoLiao();
        user.setId(222l);
        user.setUsername("JavaBean");
        //user.setLike(new String[] { "music", "book", "sport" });
        user.setProdname("guangdong");
        
        fail(doc);
        // User ->> SolrInputDocument
        fail(binder.toSolrInputDocument(user));
        // SolrDocument ->> User
        fail(binder.getBean(User.class, doc));
        
        SolrDocumentList list = new SolrDocumentList();
        list.add(doc);
        list.add(doc);
        //SolrDocumentList ->> List
        fail(binder.getBeans(User.class, list));
    }
    
    /**
     * <b>function:</b> SolrInputDocument的相關方法
     * @author hoojo
     * @createDate 2011-10-21 下午03:44:30
     */
    @Test
    public void docMethod() {
        SolrInputDocument doc = new SolrInputDocument();
        doc.addField("id", System.currentTimeMillis());
        doc.addField("name", "SolrInputDocument");
        doc.addField("age", 23, 1.0f);
        doc.addField("age", 22, 2.0f);
        doc.addField("age", 24, 0f);
        
        fail(doc.entrySet());
        fail(doc.get("age"));
        //排名有用,類似百度競價排名
        doc.setDocumentBoost(2.0f);
        fail(doc.getDocumentBoost());
        fail(doc.getField("name"));
        fail(doc.getFieldNames());//keys
        fail(doc.getFieldValues("age"));
        fail(doc.getFieldValues("id"));
        fail(doc.values());
    }
    
    /**
     * 自動補全功能
     * @param q
     * @param limit
     * @return
     */
    private List<Term> query(String q, int limit) {  
	     List<Term> items = null;  
	     SolrQuery query = new SolrQuery();  
	     query.addTermsField("spell");  
	     query.setTerms(true);  
	     query.setTermsLimit(limit);  
	     query.setTermsLower(q);  
	     query.setTermsPrefix(q);  
	     query.setQueryType("/terms");  
	     try {  
	         QueryResponse qr = server.query(query);  
	         TermsResponse resp = qr.getTermsResponse();  
	         items = resp.getTerms("spell");  
	     } catch (SolrServerException e) {  
	        items = null;  
	     }  
	     return items;  
	} 
	
    public void  spell(){
        List<Term> list = new ArrayList<Term>();  
        QueryResponse queryResponse = new QueryResponse();  
        SolrQuery query = new SolrQuery();  
        // fl=id,name&rows=0&q=*:*&facet=true&facet.field=searchText&facet.  
        // mincount=1&facet.prefix=sony  
        //facet=true&rows=0&fl=id%2Cname&facet.prefix=sony&facet.field=searchText  
        try {  
            query.setFacet(true);  
            query.setRows(0);  
            query.setQuery("*:*");  
            query.setFacetPrefix("sony");  
            query.addFacetField("searchText");  
            System.out.println(query.toString());  
            queryResponse =solrServer.query(query, METHOD.POST);  
        } catch (Exception e) {  
            // TODO: handle exception  
            e.printStackTrace();  
        }  
    }
}