solr解決訪問安全

Tomcat7,solr3.6,mmseg1.8html

1:環境的搭建java

1:解壓tomcat,solr,mmseg4jweb

2:複製dist文件夾下apache-solr.war到tomcat的webapp文件夾下,修改文件名爲solr(不應也行,這裏修改文件名方便一會地址欄的輸入)apache

3:建立solr-tomcat文件夾做爲solr的根目錄編程

4:tomcat/conf/Catalina/localhost文件夾(不存在手動建立)下建立solr.xml,文件內容以下,根據狀況,修改相應的路徑json

<Context docBase="E:/tomcat7/apache-tomcat-7.0.19/webapps/solr" reloadable="true" >瀏覽器

<Environment name="solr/home" type="java.lang.String" value="E:/solr-tomcat" override="true" />緩存

</Context>tomcat

5:複製solr解壓後,example文件夾下的solr文件夾到solr-tomcat文件夾下app

6:訪問http://localhost:8080/solr/,驗證是否配置成功(訪問後,solr-tomcat/solr文件夾下會多一個data文件夾)

 

2:配置文件的說明

1:apache-tomcat-7.0.19\conf\Catalina\localhost\solr.xml文件,用來配置solr的根目錄,目前只用到一次

2:E:\solr-tomcat\solr\solr.xml文件,目前只看到在配置多核時用到,後面講

3:E:\solr-tomcat\solr\conf\schema.xml文件(很是重要)

<fieldType name="string" class="solr.StrField" sortMissingLast="true" />配置域的類型

<field name="name" type="text_general" indexed="true" stored="true"/>配置域,在doc文檔中的用到的field和solrj中用到的域名必須在這裏配置。Index表示是否須要索引,stored是否須要存儲,multiValued表示是否有多個值

<dynamicField name="*_s" type="string" indexed="true" stored="true"/>就是動態匹配

<copyField source="name" dest="text"/>在搜索時能夠直接經過「zhang san」來搜索那麼,不須要在經過「name:zhang san」來搜索

4:E:\solr-tomcat\solr\conf\solrconfig.xml文件:緩存,請求的配置,索引的配置

 

3:瀏覽器客戶端的說明

Solr->analyze:分詞

Query String:根據索引搜索時用。eg:name:zhang san能夠經過name來搜索姓名是zhang san的人。若是配置了copyField也能夠直接經過zhang san來搜索

 

4:中文分詞的配置

1:解壓mmseg4j,拷貝mmseg4j-all-1.8.5.jar到tomcat\webapp\solr的lib目錄下

2:solr-tomcat\solr下建立dic文件夾,存放詞庫;拷貝mmseg4j下的words.dic到該目錄下

3:修改schema.xml文件,添加以下代碼(注意修改路徑)

<!--mmseg4j field types-->

<fieldType name="textComplex" class="solr.TextField" positionIncrementGap="100" >

<analyzer>

<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="E:/solr-tomcat/solr/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="E:/solr-tomcat/solr/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="E:/solr-tomcat/solr/dic"/>

<filter class="solr.LowerCaseFilterFactory"/>

</analyzer>

</fieldType>

 

 

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

 

<copyField source="simple" dest="text"/>

<copyField source="complex" dest="text"/>

4:測試中文分詞是否起做用

複製一段中文到Field value中;Field選擇name輸入complex,測試分詞

name在使用name(沒有配置中文分詞,使用默認的)再次進行測試

 

 

5:多核的配置

1:拷貝example\multicore文件夾下的core0,core1,solr.xml到solr-tomcat\solr文件夾下

2:方位http://localhost:8080/solr/

 

 

 

 

 

使用瀏覽器客戶端建立索引,搜索

4:建立索引(xml,json,cvs格式的文件cookbook)

1:複製solr解壓後的,example文件夾下的exampledocs目錄到solr-tomcat下(裏面包含了一些測試索引用到的文件)

2:命令行建立索引:E:\solr-tomcat\exampledocs>java -Durl=http://localhost:8080/solr/update -Dcommit=yes -jar post.jar m*.xml,對該文件夾下全部以m開頭的xml文件建立索引,此時solr-tomcat\solr\data文件夾下多了一些文件,有段文件,域文件,索引文件等

3:經過瀏覽器進行搜索,必須經過一個完整的分詞(一個完整的單詞,不能用a,m,z等搜索,同時this,that等也不能用於搜索)

 

5:更新索引

更新索引通常都是經過刪除索引,而後再建立

6:刪除索引

Solrj的使用

http://wiki.apache.org/solr/Solrj

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

1:建立索引(如何對一個指定格式的xml建立索引還不清楚)

對文件進行索引

public void index() throws SolrServerException, IOException {

SolrServer solrServer = new HttpSolrServer(DEFAULT_URL);

SolrInputDocument document = new SolrInputDocument();

document.addField("id", "1"); //id必須有

document.addField("name", "test");

document.addField("path", "測試"); //path須要在schema.xml中定義

solrServer.add(document);

solrServer.commit();

}

對Bean進行索引

public class SolrItem {

/**

* id,對應Solr中記錄的Id

*/

@Field("id")

public String id;

 

/**

* 員工姓名

*/

@Field("title")

public String empName;

 

/**

* 員工郵箱

*/

@Field("subject")

public String email;

 

...

}

 

public void index() throws SolrServerException, IOException {

SolrItem item = new SolrItem();

item.setId("1");

item.setEmpName("張三");

item.setEmail("test@ppstream.com");

solrServer.addBean(item);

solrServer.commit();

}

 

 

2:搜索

public void query(String query) {

SolrParams params = new SolrQuery(query);

try {

QueryResponse response = solrServer.query(params);

SolrDocumentList list = response.getResults();

for (int i = 0; i < list.size(); i++) {

fail(list.get(i));

}

catch (SolrServerException e) {

e.printStackTrace();

}

}

 

3:刪除索引

public void delete(String params) throws SolrServerException, IOException {

solrServer.deleteByQuery(params);

//solrServer.deleteById(params);

}

 

 

4:高亮顯示

public SolrDocumentList query(String str) {

SolrQuery query = new SolrQuery(str);

 

//設置高亮,如下兩種方式都行(至關於開啓高亮功能)

//query.setHighlight(true);

query.setParam("hl", "true"); //highlighting

 

//設置高亮顯示的請求,高亮顯示的內容由該參數決定,可是返回結果仍是由SolrQuery決定

//query.setParam("hl.q", "email:zhang@ppstream.com");

 

/*

* 那些字段高亮顯示,能夠用空格或者逗號分隔(有一個域的時候正常,兩個及以上沒測試經過)

* 老版本使用query.addHighlightField("name");query.addHighlightField("description");給多個字段開啓高亮功能

*/

query.setParam("hl.fl", "name");

 

//高亮顯示字段先後添加html代碼

query.setHighlightSimplePre("<font color=\"red\">");

query.setHighlightSimplePost("</font>");

 

SolrDocumentList list = new SolrDocumentList();

SolrDocument document = null;

 

QueryResponse response=new QueryResponse();

try {

SolrDocumentList documents = response.getResults();

//第一個Map的鍵是文檔的ID,第二個Map的鍵是高亮顯示的字段名

Map<String, Map<String, List<String>>> map = response.getHighlighting();

 

for(int i=0;i<documents.size();i++) {

document = documents.get(i);

document.setField("name", map.get(document.getFieldValue("id")).get("name"));

/*document.setField("email", map.get(document.getFieldValue("id")).get("email"));*/

list.add(document);

}

catch (Exception e) {

 

}

return list;

}

 

 

Solr的其餘應用

1:對一篇文章的前100個分詞字建立索引

有時可能須要對某個字段(文章的內容content)的前1000個字符建立索引並存儲,能夠在solrconfig.xml中添加<maxFieldLength>1000</maxFieldLength>實現(默認是1萬)。這裏是分詞數量,不是漢字或字母的個數。

 

2:配置中文分詞後,若是查詢「java編程思想」,會自動拆分紅java,編程,思想3個分詞依次進行查找

 

3:多條件查詢

能夠經過「編程 AND empName:XXX」進行查詢,或者「編程 OR empName:XXX」等

 

4:字段當作一個總體,不進行分詞

若是某個字段不須要使用分詞,eg:java編程思想,只有在輸入完成的書名:java編程思想纔會搜索出來,能夠在書名字段上的type使用不帶分詞的類型(schema.xml中配置)

 

5:檢索索引中的部分字段

有時索引中可能存放不少信息,eg:書名,做者,出版時間,ISBN…….;在某次查詢中,咱們只須要搜索結果書名和做者便可。能夠經過以下方式實現

SolrQuery query = new SolrQuery(param);

   //返回的結果

   String[] str = {"title", "author"};

query.setFields(str);

 

6:Solr的分頁

         SolrQuery query = new SolrQuery("*:* AND (empName:XXX OR empName:XX)");

    query.setHighlight(true);

    query.setStart(0);

    query.setRows(2);

    QueryResponse response = solrServer.query(query);

    long totalCount = response.getResults().getNumFound();

 totalCount返回的是知足條件的總記錄條數,並不必定是0或2

 

7:solrj高亮顯示時,只顯示字段部份內容

SolrDocumentList list = response.getResults();

   Map<String, Map<String, List<String>>> map = response.getHighlighting();

   //對應的高亮字段(假設是content)。在list中顯示正確,map中顯示的只是content中的一部分。

   query.setHighlightFragsize(100000); //能夠經過這種方法改變,設置一個比list中,對應content內容大的數字

query.setHighlightSnippets(0);//或者設置高亮片斷爲0,這樣關鍵字也就不會在高亮顯示

 

8:搜索條件的部分關鍵字高亮顯示

有時咱們查詢根據條件「java OR (empId:1000 AND empId:1001)」搜索時,結果若是高亮顯示,可能出現1000,1001數字也會高亮,可是咱們只但願java關鍵字高亮,這個時候能夠用下面的方法

   query.setParam("hl.q", "lucene solr");只對lucene和solr關鍵字進行高亮顯示(solr不做爲搜索條件也能夠)

 

 

9:顯示第一個匹配關鍵字附近的部份內容

   有時咱們須要顯示檢索出內容的一部分(在列表頁,只須要顯示一個概要信息),這時候能夠經過設置query.setHighlightFragsize(100000);的大小來控制

 

10:schema文件,copyField配置

<!-- 感受使用copyField的做用是。

                1:不須要在輸入title:XXX,只需簡單XXX便可查詢

                2:將title,content中輸入的內容所有放到text一個字段上進行,能夠簡化查詢不須要過多的判斷

                3:須要注意的是:source對應域的類型要和dest域對應的類型相兼容

    -->

    <copyField source="title" dest="complex"/>

    <copyField source="content" dest="complex"/>

 

 

 

 

 

11:自動補全

搜索時在title和content上進行搜索,因此自動補全時要在title和content上同時進行。可是自動補全只能在一個字段上進行(目前我知道這樣),因此就建立一個新字段searchField=title+」,」+content用來進行自動補全的提示,該字段僅用來索引不須要存儲。

SolrQuery query = new SolrQuery(q); 

query.addTermsField(searchField);

query.setTerms(true); 

query.setTermsLimit(limit); 

query.setTermsLower(pre); 

query.setTermsPrefix(pre);

query.setQueryType("/terms");

 

QueryResponse qr = solrServer.query(query);

       TermsResponse resp = qr.getTermsResponse();

 List<Term> list = resp.getTerms(searchField);

這種搜索存在的問題:

1: q:empName:XXX AND projecteId:19    pre:lucen   在搜索時,返回的TermsResponse結果只應用了pre一個條件

2: title,content沒法配置copyField字段使用complex(緣由及解決辦法沒找到)

 

解決方法:改用Facet替換Term

SolrQuery query = new SolrQuery(q);

 

        query.setFacet(true);

        query.addFacetField(searchField);

        query.setFacetLimit(limit);

        query.setFacetPrefix(pre);

 

        QueryResponse qr = solrServer.query(query);

        List<FacetField> fss = qr.getFacetFields();

        FacetField ff = fss.get(0);

  return ff.getValues();

  返回的fss結果仍然是根據pre一個條件返回的結果集,可是不知足條件query的結果集中,對應的count爲0,即出現了0次

 

12:solr刪除索引後,索引文件還存在,可是搜索結果已經不存在

 

 

13:添加tomcat驗證,防止用戶直接經過地址欄訪問solr,進行修改刪除索引

   1:修改tomcat-user.xml文件

<role rolename="tomcat"/>

  <role rolename="role1"/>

  <role rolename="manager"/>

  <role rolename="admin"/>

  <role rolename="manager-gui"/>

  <user username="tomcat" password="tomcat" roles="tomcat"/>

  <user username="both" password="tomcat" roles="tomcat,role1"/>

  <user username="role1" password="tomcat" roles="role1"/>

  <user username="zhchx" password="zhchx" roles="admin,manager,manager-gui"/>

2:修改solr的web.xml文件,添加以下代碼,對全部的請求,都須要tomcat用戶及密碼的驗證

<security-constraint>

       <web-resource-collection>

           <web-resource-name>solr</web-resource-name>

           <url-pattern>/*</url-pattern>

           <http-method>GET</http-method>

           <http-method>POST</http-method>

       </web-resource-collection>

       <auth-constraint>

           <description>This applies only to the "tomcat" security role</description>

           <role-name>admin</role-name>

       </auth-constraint>

   </security-constraint>

 

   <login-config>

       <auth-method>BASIC</auth-method>

   </login-config>

   <security-role>

       <role-name>admin</role-name>

   </security-role>

3:使用該方法後,經過solrj也不能直接訪問,修改以下

String url = PropertiesSon.getText("solr.serverUrl");

            String username = PropertiesSon.getText("solr.username");

            String password = PropertiesSon.getText("solr.password");

            String host = PropertiesSon.getText("solr.host");

            int port = Integer.parseInt(PropertiesSon.getText("solr.port"));

           

            DefaultHttpClient httpclient = new DefaultHttpClient();

            httpclient.getCredentialsProvider().setCredentials(

                    new AuthScope(host, port),

                    new UsernamePasswordCredentials(username, password));

 

            solrServer = new HttpSolrServer(url, httpclient);

4:使用該方法建立時,刪除添加索引報錯「Cannot retry request with a non-repeatable request entity.」

修改方法:url用http://username:password@10.1.11.165:8081/solr取代http://10.1.20.57:8081/solr(httpclient使用 4.2是時正常,使用4.1時,在刪除新增索引仍然會報上面的錯誤)

相關文章
相關標籤/搜索