1. 程式人生 > >基於solr實現商品資訊的全文檢索(windwons)

基於solr實現商品資訊的全文檢索(windwons)

搭建環境

windows下tomcat+solr

 

相關軟體準備

1.安裝JDK

2.下載tomcat

3.下載solr-4.10.3.tgz.tgz

4.下載IK分詞器(IKAnalyzer2012FF_hf1.rar)

 

安裝步驟

1.解壓solr-4.10.3.tgz.tgz

2.複製example\webapps下的solr.war到tomcat\webapp下

3.解壓solr.war,然後刪除solr.war(要在tomcat停止的情況下進行操作)

4.建立solr_home,修改solr\WEB-INF\web.xml,配置如下

   <env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>D:/qjw/apache-tomcat-7.0.91-windows-x64/solr_home</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>

<env-entry-value>為sorl_home的路徑

5.解壓IKAnalyzer2012FF_hf1.rar

6.在solr\WEB-INF下建立classes

7.複製IKAnalyzer.cfg.xml,ext_stopword.dic,mydict.dic到classes檔案中

8.啟動tomcat,在瀏覽器中輸入http://localhost:8080/solr進入solr的web介面,solr會對做solr_home初始化操作

使用solr(配置schema.xml)

1.進入solr_home\collection1\conf中

2.編輯schema.xml

在檔案最後加入如下配置

<fieldType name="text_ik" class="solr.TextField">
    <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
<field name="item_title" type="text_ik" indexed="true" stored="true"/>
<field name="item_sell_point" type="text_ik" indexed="true" stored="true"/>
<field name="item_price"  type="long" indexed="true" stored="true"/>
<field name="item_image" type="string" indexed="false" stored="true" />
<field name="item_category_name" type="string" indexed="true" stored="true" />
<field name="item_desc" type="text_ik" indexed="true" stored="false" />
 

<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="item_title" dest="item_keywords"/>
<copyField source="item_sell_point" dest="item_keywords"/>
<copyField source="item_category_name" dest="item_keywords"/>
<copyField source="item_desc" dest="item_keywords"/>

 

程式設計實現

1.架構圖

架構圖

2.建立java pojo屬性對應copyField中的屬性

3.利用solrj 介面實現基本的操作

package com.jcstool.solr;

import com.jcstool.solr.callback.FieldSetCallback;
import com.jcstool.solr.callback.HighlightCallback;
import com.jcstool.solr.callback.QueryCallback;
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.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 java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * solr 輔助類
 */
public class SolrHelper<T,PK>{
    private SolrServer solrServer = null;


    public SolrHelper(SolrServer solrServer) {
        this.solrServer = solrServer;
    }

    /**
     * 新增一個實體
     * @param t 實體
     * @param properties 屬性列表
     */
    public void add(T t,List<String> properties){
        List<T> list = new ArrayList<T>();
        list.add(t);
        add(list,properties);
    }
    public void add(T t,FieldSetCallback callback){
        List<T> list = new ArrayList<T>();
        list.add(t);
        add(list,callback);
    }

    /**
     * 批量新增
     * @param list 實體集合
     * @param callback
     */
    public void add(List<T> list, FieldSetCallback callback){
        if(null == list || list.size() == 0 ) {
            return;
        }
        List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
        List<Field> fields = ReflectUtil.getAllFields(list.get(0).getClass());
        for (T obj : list) {
            SolrInputDocument doc = new SolrInputDocument();
            callback.setFiled(obj,doc);
            docs.add(doc);
        }
        try {
            solrServer.add(docs);
            solrServer.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 批量新增
     * @param list 實體集合
     * @param properties 屬性列表
     */
    public void add(List<T> list, List<String> properties){
        if(null == list || list.size() == 0 ) {
            return;
        }
        List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
        List<Field> fields = ReflectUtil.getAllFields(list.get(0).getClass());
        for (T obj : list) {
            SolrInputDocument doc = new SolrInputDocument();
            for (Field field : fields) {
                for (String property : properties) {
                    if(property.equals(field.getName())) {
                        doc.addField(property, ReflectUtil.invokeGetter(obj,property));
                    }
                }
            }
            docs.add(doc);
        }
        try {
            solrServer.add(docs);
            solrServer.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public   void add(T obj) {
        try {
            this.solrServer.addBean(obj);
            this.solrServer.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 新增多個索引物件
     *
     */
    public  <T> void addBeans(List<T> list) {
        try {
            this.solrServer.addBeans(list);
            this.solrServer.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    /**
     * 根據ID刪除
     * @param pk
     * @return
     * @throws IOException
     * @throws SolrServerException
     */
    public UpdateResponse deleteById(String pk) throws IOException, SolrServerException {
        UpdateResponse rsp = solrServer.deleteById(pk);
        solrServer.commit();
        return rsp;
    }

    /**
     * 清空資料
     * @return
     */
    public UpdateResponse clear(){
        return deleteByQuery("*:*");
    }

    /**
     * 根據查詢語句刪除索引
     * @param query
     * @return
     */
    public  UpdateResponse deleteByQuery(String query) {
        try {
            UpdateResponse rsp = solrServer.deleteByQuery(query);
            solrServer.commit();
            return rsp;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    public T queryById(String id, Class<?> entityClass) {
        T obj = null;
        try {
            obj = (T) entityClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        SolrQuery query = new SolrQuery();
        query.setQuery("id:" + id);
        QueryResponse response = null;
        try {
            response = solrServer.query(query);
        } catch (Exception e) {
            e.printStackTrace();
        }
        SolrDocumentList docs = response.getResults();
        if(null == docs || docs.size() == 0) {
            return null;
        }
        SolrDocument doc = docs.get(0);
        List<Field> fields = ReflectUtil.getAllFields(obj.getClass());
        for (Field field : fields) {
            String propertyName = field.getName();
            Object propertyValue =  doc.getFieldValue(propertyName);
            Class<?> propertyClass = field.getType();
            if(propertyClass.equals(Integer.class)) {
                ReflectUtil.setFieldValue(obj,propertyClass,propertyName,propertyValue);
            } else {
                ReflectUtil.setFieldValue(obj,propertyClass,propertyName,propertyValue);
            }
        }
        return obj;
    }

    public SolrQuery createQuery(String queryString){
        //根據查詢條件拼裝查詢物件
        //建立一個SolrQuery物件
        SolrQuery query = new SolrQuery();
        //設定查詢條件
        query.setQuery(queryString);
        return query;
    }

    public  <T> Page<T> query(Page<T> page, SolrQuery solrQuery, Class<?> entityClass) {
        return query(page, solrQuery, entityClass, new HighlightCallback<T>(){
            public T set(T t, QueryResponse queryResponse, SolrDocument doc) {
                return t;
            }
        });
    }
    /**
     * solr獲取的分頁物件
     * @param page
     * @param solrQuery
     * @param entityClass
     * @param <T>
     * @return
     */
    public  <T> Page<T> query(Page<T> page, SolrQuery solrQuery, Class<?> entityClass, HighlightCallback callback) {
        solrQuery.setStart(page.getStartOfPage());//開始索引
        solrQuery.setRows(page.getPageSize());//分頁的數量
        QueryResponse queryResponse = null;
        try {
            queryResponse = solrServer.query(solrQuery);
        } catch (Exception e) {
            e.printStackTrace();
        }
        SolrDocumentList docs = queryResponse.getResults();
        List<T> list = new ArrayList<T>(0);



        for(SolrDocument doc : docs){
            T obj = null;
            try {
                obj =  (T) entityClass.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            List<Field> fields = ReflectUtil.getAllFields(obj.getClass());
            for (Field field : fields) {
                String propertyName = field.getName();
                Object propertyValue =  doc.getFieldValue(propertyName);
                Class<?> propertyClass = field.getType();
                if(propertyClass.equals(Integer.class)) {
                    ReflectUtil.setFieldValue(obj, propertyClass, propertyName, propertyValue);
                } else {
                    ReflectUtil.setFieldValue(obj, propertyClass, propertyName, propertyValue);
                }

            }
            callback.set(obj,queryResponse,doc);
            list.add(obj);
        }
        page.setTotalRecord(docs.size());
        page.setResults(list);
        return page;
    }


}

4.將資料庫中的資料匯入到solr中

 

說明:後面的java操作實現查詢功能就不提供程式碼了,根據架構圖實現就好了。

第一次要講資料庫中的資料全部匯入到solr中,以後匯入資料的話,可以使用mq或其他的訊息中介軟體去實現有資料新增到資料庫時,同時匯入solr

 

windows下配置好的solr server 下載