solr進階四:建立檔案索引
索引資料來源並不會一定來自於資料庫、XML、JSON、CSV這類結構化資料,很多時候也來自於PDF、word、html、word、MP3等這類非結構化資料,從這類非結構化資料建立索引,solr也給我們提供了很好的支援,利用的是apache tika。
下面我們來看看在solr4.10中如何從pdf檔案建立索引。
先配置檔案索引
新建core,儲存檔案型索引,具體步驟參考:
匯入jar包
在工作目錄下新建一個extract資料夾,用來存放solr擴充套件的jar包。
\solr_tomcat\solr\pdf_core\extract
拷貝\solr-4.10.2\dist下的solr-cell-4.10.2.jar
\solr-4.10.2\contrib\extraction\lib下的索引jar包拷貝到extract資料夾中。
配置solrconfig.xml
新增請求解析配置:
<requestHandler name="/extract" class="solr.extraction.ExtractingRequestHandler" > <lst name="defaults"> <str name="fmap.content">text</str> <str name="lowernames">true</str> <str name="uprefix">attr_</str> <str name="captureAttr">true</str> </lst> </requestHandler>
指定依賴包位置:
<span style="font-size:18px;"><lib dir="extract" regex=".*\.jar" /></span>
注意,這個相對位置不是相對於配置檔案所在資料夾位置,而是相對core主目錄的。比如我的配置檔案在\solr_tomcat\solr\pdf_core\conf, 但是我的jar包在\solr_tomcat\solr\pdf_core\extract那麼我的相對路徑就是extract而不是../extract。
配置schema.xml,配置索引欄位的型別,也就是field型別。
其中text_general
注意:如果是複製貼上core來新建core的話,原來的配置檔案有些field是已經定義的,要注意把重複定義的去掉一個!
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
<fieldtype name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
配置索引欄位,也就是field
其中有個動態型別欄位,attr_*,這個是什麼意思呢。也就是solr在解析檔案的時候,檔案本身有很多屬性,具體有哪些屬性是不確定的,solr全部把他解析出來以attr作為字首加上檔案本身的屬性名,組合在一起就成了field的名稱。
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
<field name="text" type="text_general" indexed="true" stored="true"/>
<field name="_version_" type="long" indexed="true" stored="true"/>
<dynamicField name="attr_*" type="text_general" indexed="true" stored="true" multiValued="true"/>
到這裡solr服務端的配置以及完成了。
測試類CreateIndexFromPDF.java
Solrj4.10裡面ContentStreamUpdateRequest的addFile方法多了一個contentType引數,指明內容型別。ContentType請參看:ContentType
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
import java.io.File;
import java.io.IOException;
/**
* Created by Lhx on 14-12-4.
*/
public class CreateIndexFromPDF {
public static void indexFilesSolr(String fileName, String solrId) throws IOException, SolrServerException {
String urlString = "http://localhost:8080/solr/pdf_core";
SolrServer solr = new HttpSolrServer(urlString);
ContentStreamUpdateRequest up = new ContentStreamUpdateRequest("/extract");
String contentType = "application/pdf";
up.addFile(new File(fileName), contentType);
up.setParam("literal.id", solrId);
up.setParam("uprefix","attr_");
up.setParam("fmap.content","attr_content");
up.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);
solr.request(up);
QueryResponse rsp = solr.query(new SolrQuery("*:*"));
System.out.println(rsp);
}
public static void main(String[] args) {
String fileName = "F:\\Sencha_Touch_2.0使用者指南(中文版).pdf";
String solrId = "Sencha_Touch_2.0使用者指南(中文版).pdf";
try {
indexFilesSolr(fileName,solrId);
} catch (IOException e) {
e.printStackTrace();
} catch (SolrServerException e) {
e.printStackTrace();
}
}
}
執行上面程式碼,便把我們的pdf檔案上傳到solr伺服器,解析、建立索引。
後面的solr.query是執行一個查詢,查詢解析索引後結果。解析後pdf就變成了純文字的內容,在控制檯可以看到很多文件其他資訊。
Solr解析完pdf、建立索引後,我們也可以在solr的管理介面檢視索引結果。如下圖。
選擇“Query”,直接點選“Execute Query”按鈕就可以了:
後記:
重啟tomcat後報重複定義欄位的錯誤,這個在前面的實踐中就有這個錯誤,所以很快就在schema.xml中找到重複定義的id和long等型別欄位,刪掉就可以了。
接著啟動tomcat,還是報出無法載入某某jar包的提示錯誤,後來才發現
<lib dir="extract" regex=".*\.jar" />
這個dir指定的目錄地址寫錯了,導致tomcat報錯。
啟動tomcat後再也沒有報錯,在java控制檯執行程式碼,報出以下錯誤:
原來是我把urlString地址寫錯了,寫成了:
http://localhost:8080/solr
沒有指定究竟上傳到哪個指定的core裡面,修改後就能提交PDF文件資訊了。
附錄:
solrconfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!--
This is a stripped down config file used for a simple example...
It is *not* a good example to work from.
-->
<config>
<luceneMatchVersion>4.10.2</luceneMatchVersion>
<!-- The DirectoryFactory to use for indexes.
solr.StandardDirectoryFactory, the default, is filesystem based.
solr.RAMDirectoryFactory is memory based, not persistent, and doesn't work with replication. -->
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>
<dataDir>${solr.core0.data.dir:}</dataDir>
<!-- To enable dynamic schema REST APIs, use the following for <schemaFactory>:
<schemaFactory class="ManagedIndexSchemaFactory">
<bool name="mutable">true</bool>
<str name="managedSchemaResourceName">managed-schema</str>
</schemaFactory>
When ManagedIndexSchemaFactory is specified, Solr will load the schema from
he resource named in 'managedSchemaResourceName', rather than from schema.xml.
Note that the managed schema resource CANNOT be named schema.xml. If the managed
schema does not exist, Solr will create it after reading schema.xml, then rename
'schema.xml' to 'schema.xml.bak'.
Do NOT hand edit the managed schema - external modifications will be ignored and
overwritten as a result of schema modification REST API calls.
When ManagedIndexSchemaFactory is specified with mutable = true, schema
modification REST API calls will be allowed; otherwise, error responses will be
sent back for these requests.
-->
<schemaFactory class="ClassicIndexSchemaFactory"/>
<updateHandler class="solr.DirectUpdateHandler2">
<updateLog>
<str name="dir">${solr.core0.data.dir:}</str>
</updateLog>
</updateHandler>
<!-- realtime get handler, guaranteed to return the latest stored fields
of any document, without the need to commit or open a new searcher. The current
implementation relies on the updateLog feature being enabled. -->
<requestHandler name="/get" class="solr.RealTimeGetHandler">
<lst name="defaults">
<str name="omitHeader">true</str>
</lst>
</requestHandler>
<requestHandler name="/replication" class="solr.ReplicationHandler" startup="lazy"/>
<requestDispatcher handleSelect="true">
<requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" formdataUploadLimitInKB="2048"/>
</requestDispatcher>
<requestHandler name="standard" class="solr.StandardRequestHandler" default="true"/>
<requestHandler name="/analysis/field" startup="lazy" class="solr.FieldAnalysisRequestHandler"/>
<requestHandler name="/update" class="solr.UpdateRequestHandler"/>
<requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers"/>
<requestHandler name="/admin/ping" class="solr.PingRequestHandler">
<lst name="invariants">
<str name="q">solrpingquery</str>
</lst>
<lst name="defaults">
<str name="echoParams">all</str>
</lst>
</requestHandler>
<!--新新增的內容-->
<requestHandler name="/extract" class="solr.extraction.ExtractingRequestHandler">
<lst name="defaults">
<str name="fmap.content">text</str>
<str name="lowernames">true</str>
<str name="uprefix">attr_</str>
<str name="captureAttr">true</str>
</lst>
</requestHandler>
<lib dir="extract" regex=".*\.jar"/>
<!-- config for the admin interface -->
<admin>
<defaultQuery>solr</defaultQuery>
</admin>
</config>
schema.xml
<?xml version="1.0" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<schema name="example core zero" version="1.1">
<!-- general -->
<field name="type" type="string" indexed="true" stored="true" multiValued="false"/>
<field name="name" type="string" indexed="true" stored="true" multiValued="false"/>
<field name="core0" type="string" indexed="true" stored="true" multiValued="false"/>
<!-- field to use to determine and enforce document uniqueness. -->
<uniqueKey>id</uniqueKey>
<!-- field for the QueryParser to use when an explicit fieldname is absent -->
<defaultSearchField>name</defaultSearchField>
<!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
<solrQueryParser defaultOperator="OR"/>
<!--新新增的,其中long、String等欄位原來配置檔案就有,注意刪除-->
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
<fieldtype name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
<field name="text" type="text_general" indexed="true" stored="true"/>
<field name="_version_" type="long" indexed="true" stored="true"/>
<dynamicField name="attr_*" type="text_general" indexed="true" stored="true" multiValued="true"/>
</schema>
參考文章:
相關推薦
solr進階四:建立檔案索引
索引資料來源並不會一定來自於資料庫、XML、JSON、CSV這類結構化資料,很多時候也來自於PDF、word、html、word、MP3等這類非結構化資料,從這類非結構化資料建立索引,solr也給我們提供了很好的支援,利用的是apache tika。 下面我們來看看在sol
Android進階四:Databinding的使用(基礎篇)
Data Binding是2015年Google I/O大會上提出的,從Beta版至今,Data Binding已經是一個可用度較高,也能帶來實際生產力提升的技術。 Data Binding顧名思義就是資料繫結,是Google對MVVM在Android上的
solr進階九:solr對數字和單個字元的搜尋
solr中配有分詞器,但分詞器裡面有大寫轉換為小寫的過濾器時,數字就會被過濾。比如123中國ABC。123就會被過濾掉了,所以才查1|12|123都會失敗。 根據賬號來搜尋,當賬號在資料庫中是整型
分針網——每日分享:JavaScript進階(四)js字符串轉換成數字的三種方法
加入職業技能圈 q群:272292492 更多文章:www.f-z.cn 在js讀取文本框或者其它表單數據的時候獲得的值是字符串類型的,例如兩個文本框a和b,如果獲得a的value值為11,b的value值為9 ,那麽a.valu
Java進階(四十二)Java中多執行緒使用匿名內部類的方式進行建立3種方式
Java中多執行緒使用匿名內部類的方式進行建立3種方式 package cn.edu.ujn.demo; // 匿名內部類的格式: public class ThreadDemo {
android進階4step1:android小知識 檔案儲存
檔案儲存 作為一個開發者,我們經常需要通過快取一些檔案到 SD 卡中,常見的方式就是,通過: File sdCard = Environment.getExternalStorageDirectory(); 獲取 SD 卡根目錄,然後自定義檔案/檔名進行檔案儲存.這樣做法的結果就是,當手
服務端技術進階(四)一篇文讀懂分散式系統本質:高吞吐、高可用、可擴充套件
服務端技術進階( 四)一篇文讀懂分散式系統本質:高吞吐、高可用、可擴充套件 承載量是分散式系統存在的原因 當一個網際網路業務獲得大眾歡迎的時候,最顯著碰到的技術問題,就是伺服器非常繁忙。當每天有1000萬個使用者訪問你的網站時,無論你使用什麼樣的伺服
websphere服務四:建立概要檔案、刪除概要檔案
cd /usr/IBM/WebSphere/AppServer/bin 檢視刪除概要 ./manageprofiles.sh -listProfiles [Dmgr01, AppSrv01] ./manageprofiles.sh -delete -profileNam
進階教程:用Python建立全新二層神經結構
全文共5234字,預計學習時長10分鐘 圖片來源:unsplash.com/@alinnnaaaa 本文將介紹如何建立進階
四:建立高級web測試計劃
cookie 手動 建立 fine support 技術分享 瀏覽器 fix agent 發送帶有Header的請求 參考:http://jmeter.apache.org/usermanual/build-adv-web-test-plan.html#header_m
HTML5 進階系列:indexedDB 數據庫
連接數據庫 function request html5 客戶端 前言在 HTML5 的本地存儲中,有一種叫 indexedDB 的數據庫,該數據庫是一種存儲在客戶端本地的 NoSQL 數據庫,它可以存儲大量的數據。從上篇:HTML5 進階系列:web Storage ,我們知道
Python學習之旅—面向對象進階知識:類的命名空間,類的組合與繼承
ati error role ont 之前 obj say 報錯 抽象 前言 上篇博客筆者帶領大家初步梳理了Python面向對象的基礎知識,本篇博客將專註於解決三個知識點:類的命名空間,類的組合以及面向對象的三大特性之一繼承,一起跟隨筆者老看看今天的內容吧。 1.
Android進階筆記:AIDL內部實現詳解 (二)
ucc == 筆記 null stack 直接 android 最好 public 接著上一篇分析的aidl的流程解析。知道了aidl主要就是利用Ibinder來實現跨進程通信的。既然是通過對Binder各種方法的封裝,那也可以不使用aidl自己通過Binder來實現跨進
java 進階一:代理和動態代理
實現 public rgs tostring 開源項目 body llb ack code 靜態代理: 定義頂級接口:Iservice //目標類和代理類都實現該接口 public interface Iservice { public String serv
用裝飾器做一個登陸功能(進階):
read AD OS pos 商城 *args readline wrapper 改變 1 dic = { 2 ‘username‘:None, 3 ‘status‘:False 4 } 5 def login(flag): # 傳入
面向對象進階6:元類
ise and 否則 tag weak wal 方法 pan strong 六 練習題 練習一:在元類中控制把自定義類的數據屬性都變成大寫 class Mymetaclass(type): def __new__(cls,name,bases,attrs):
Python爬蟲新手進階版:怎樣讀取非結構化、圖像、視頻、語音數據
image clas 訓練 在線的 功能 方式 base64編碼 contain width 通過open讀取之後會返回一個圖像文件對象,後續所有的圖像處理都基於該對象進行。上述代碼執行後,通過 img.show() 會調用系統默認的圖像瀏覽器查看打
T-SQL查詢進階--理解SQL Server中索引的概念,原理以及其他
工具 def microsoft 需要 blog b- eve 實現 中一 簡介 在SQL Server中,索引是一種增強式的存在,這意味著,即使沒有索引,SQL Server仍然可以實現應有的功能。但索引可以在大多數情況下大大提升查詢性能,在OLAP
進階篇:3.2.4)鈑金件-材料選擇
沒有 3.5 3.1 進階 暴露 font 加工 生產線 速度 3.常用鈑金材料介紹 適合於沖壓加工的鈑金材料非常多,本書介紹廣泛應用於電子電器行業的鈑金材料。 3.1 普通冷軋板SPCC SPCC是指鋼錠經過冷軋機連續軋制成要求厚度的鋼板卷料或片料。SPCC表面沒有
Xadmin進階一:如何增加一列
init 9.png pla plugin cto object 實現 list 下標 主要實現參考 relate.py插件,通過繼承BaseAdminPlugin實現,實現效果: 主要的的代碼如下: from xadmin.views import BaseAdminP