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---------------------------------------------------------------