1. 程式人生 > >Solr使用SolrDocumentList獲取資料庫的資料,常見異常

Solr使用SolrDocumentList獲取資料庫的資料,常見異常

最近在初學Solr,使用SolrDocumentList獲取資料庫的資料,遇到了幾個常見異常,現在在這裡記錄下來,以便日後查詢

一、配置檔案data-config.xml

這個檔案MySql連線的配置,現在放上我此次專案的檔案內容

<dataConfig>
    <!-- 這是mysql的配置,學會jdbc的都應該看得懂 -->
    <dataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/mytest" user="king" password="123456"/>
    <document>
        <!-- name屬性,就代表著一個文件,可以隨便命名 -->
        <!-- query是一條sql,代表在資料庫查找出來的資料 -->
        <entity name="artical" query="select * from artical">
            <!-- 每一個field對映著資料庫中列與文件中的域,column是資料庫列,name是solr的域(必須是在managed-schema檔案中配置過的域才行) -->
			
            <field column="artical_id" name="id"/>
            <field column="img" name="img"/>
            <field column="date" name="date"/>
            <field column="title" name="title"/>
            <field column="author" name="author"/>
            <field column="type" name="type"/>
            <field column="look" name="look"/>
        </entity>
    </document>
</dataConfig>

底下所有的<field>都是關於資料庫中列與Solr文件中的域,column是資料庫列的名稱,name是solr的域名稱

1、name配置不相符合

          如果data-config.xml中間有那個域的名稱在另外一個檔案managed-schema中的配置不相符,就會出現錯誤。

2、資料庫的連線問題

          url="jdbc:mysql://localhost:3306/mytest"

          user="king"

          password="123456"

         這幾個引數每個都要與自己資料庫的對應,不然資料庫連線不成功,就會出現異常。

二、 配置中文分詞器異常

managed-schema 檔案主要相關 配置中文分詞器。

一般來說,如果按照網上的Solr教程一步步盡心配置的,都會有以下程式碼:

<fieldType name="text_smartcn" class="solr.TextField" positionIncrementGap="100"> 
   <analyzer type="index"> 
       <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
	   <uniqueKey>id</uniqueKey>
	   <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
	  <field name="img" type="string" indexed="false" stored="true"  /> 
	  <field name="date" type="text_smartcn" indexed="true" stored="true"  /> 
	  <field name="title" type="text_smartcn" indexed="true" stored="true"  /> 
	  <field name="author" type="text_smartcn" indexed="true" stored="true"  /> 
	  <field name="type" type="text_smartcn" indexed="true" stored="true"  /> 
	  <field name="look" type="int" indexed="false" stored="true"  /> 
	  
	  
   </analyzer> 
   <analyzer type="query">
         <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
		 <uniqueKey>id</uniqueKey>
	   <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
	  <field name="img" type="string" indexed="false" stored="true"  /> 
	  <field name="date" type="text_smartcn" indexed="true" stored="true"  /> 
	  <field name="title" type="text_smartcn" indexed="true" stored="true"  /> 
	  <field name="author" type="text_smartcn" indexed="true" stored="true"  /> 
	  <field name="type" type="text_smartcn" indexed="true" stored="true"  /> 
	  <field name="look" type="int" indexed="false" stored="true"  /> 
   </analyzer> 
 </fieldType> 

   這個檔案需要注重一下問題:

1、<fieldType>合格標籤的屬性name是 在Solr選擇的中文分詞器名稱

   我這裡選擇的是Solr官網推薦的smartcn,其他的屬性基本上不需要變

2、analyzer有兩個type,一個是index,一個是query,所有的<field>都要存在

    index的配置是關於索引,query的配置的關於查詢,Solr在新建立一個Core的時候,會首先遍歷執行index的配置,之後在進行查詢的時候,就要涉及到query的配置。

  3、Document is missing mandatory uniqueKey field: id

這個異常我看到網上都有解析,但是說的和我的問題有點不對應,最後在自己研究之後發現了錯誤,希望這個記錄可以幫助到同樣是在網上查詢Solr教程的人。

這個問題主要是因為Solr 的solrconfig配置檔案中定義了<uniqueKey>id</uniqueKey>,默認了ID 是唯一的。

但是如果在配置檔案中沒有配置到id,就會出現這個異常。

我當時在managed-schema 檔案中想當然的寫了

<uniqueKey>arcicle_id</uniqueKey>

我以為這個id就是我在資料庫裡面描述的id,為了對應,我寫的一模一樣,當出現這個問題之後,我還在懷疑,是不是哪裡還有一個關於id的描述,與我這個配置出現了衝突。

最後只要把這個id,設定成預設就可以了。

<uniqueKey>id</uniqueKey>

但是要注意的一點是本文提到的常見異常一中的name配置不相符合問題

三、Max Doc等於0

1、fectch 6,Process 0,說明沒有建立索引成功; 

2、fectch 6,process 6,也不一定說明建立索引成功;

檢視

collection1下 Max Doc:6,才代表成功。

這個引數說明Solr從資料庫中獲取或者修改的記錄條數,如果為0,說明就沒有執行。

這個異常要注意看solrconfig.xml檔案下面

<requestHandler name="/dataimport" class="solr.DataImportHandler">
      <lst name="defaults">
            <str name="config">data-config.xml</str>
      </lst>
  </requestHandler>

底下的檔名稱和自己設定的是不是一樣,不然系統會找不到,SolrDocumentList獲取不到值

或者就是之前哪裡的配置不對,可以直接定位到Solr的配置問題,不許需要思考從資料庫獲取值的過程。

 


最後在放置一下我在客戶端操作Solr的程式碼,希望有幫助。

package com.frist.utils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
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.params.MapSolrParams;
import org.apache.solr.common.params.SolrParams;

public class SolrUtils {

	// solr url
	private final static String BASE_URL = "http://localhost:8080/solr";

	public static HttpSolrClient getSolrClient() {
		/*
		 * 設定超時時間 .withConnectionTimeout(10000) .withSocketTimeout(60000)
		 */
		return new HttpSolrClient.Builder(BASE_URL).withConnectionTimeout(10000).withSocketTimeout(60000).build();
	}

	// 查詢
	public void testQuery() throws IOException, SolrServerException {
		System.out.println("準備進入查詢。。。");
		HttpSolrClient solrClient = getSolrClient();
		// 定義查詢條件
		Map<String, String> params = new HashMap<String, String>();
		params.put("q", "*:*");
		SolrParams mapSolrParams = new MapSolrParams(params);
		// 執行查詢 第一個引數是collection,就是我們在solr中建立的core
		QueryResponse response = solrClient.query("new_core", mapSolrParams);
		// 獲取結果集
		SolrDocumentList results = response.getResults();
		System.out.println(results.size());
		for (SolrDocument result : results) {

			System.out.println(result);
		}
	}

	// 新增
	public void testAdd() throws IOException, SolrServerException {
		HttpSolrClient solrClient = getSolrClient();
		// 定義資料 solr輸入文件 資料結構為Map
		SolrInputDocument inputDocument = new SolrInputDocument();
		inputDocument.addField("id", "123");
		inputDocument.addField("roleName", "角色名稱");
		// 執行新增 ps:如果id相同,則執行更新操作
		// 要指定操作的collection 就是solr-home下定義的core
		UpdateResponse add = solrClient.add("new_core", inputDocument);
		// 提交新增/更新
		solrClient.commit("RoleVO");
	}

	// 刪除
	public void testDelete() throws IOException, SolrServerException {
		HttpSolrClient solrClient = getSolrClient();
		// 通過id刪除 執行要刪除的collection(core)
		solrClient.deleteById("new_core", "123");
		// 還可以通過查詢條件刪除
		// solrClient.deleteByQuery("RoleVO", "查詢條件");
		// 提交刪除
		solrClient.commit("new_core");
	}
}

---------------------------------------------------------------------------end---------------------------------------------------------------