Solr 嵌入式开发

最近正在研究solr,solr分为服务性的搜索还嵌入式的搜索(不需要启动solr服务,直接和自己的程序整合在一块)。对于添加solr服务的搜索apache的官方说的很清楚,现在只是介绍下嵌入式的搜索。
1.配置下serverhome 在src下面。建立一个search.properties(可以自己命名) serarchServerHome=E:\\Project\\centersitesolr\\WebRoot\\solr\\multicore\\ (此路径为存放索引的路径,book,core0,core1为不同的索引服务)
2.在给定的serverhome下 建立一个search.xml(名字可以自己命名,指定solr服务)
<?xml version='1.0' encoding='UTF-8'?> <solr persistent='true'>
<cores adminPath='/admin/cores'>
<core name='core1' instanceDir='core1/'/>
<core name='core0' instanceDir='core0/'/>
<core name='book' instanceDir='book/'/>
</cores>
</solr>
3. 先定义一个SearchServerException
package com.sendian.search.solr
import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.SolrServerException;

public class SearchServerException extends RuntimeException {
Logger logger
= Logger.getLogger(SearchServerException.class);
public SearchServerException(String message) {
super(message);
logger.warn(message);
}

private static final long serialVersionUID = -6150092853751278477L;

}
4.定义一个factory
package com.sendian.search.solr;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.SolrServer;

import com.sendian.search.solr.server.EmbeddedServerContainer;

public class SearchServerFactory {
private static Logger logger = Logger.getLogger(SearchServerFactory.class);
private static Map<String,SolrServer> searchServerMap = Collections.synchronizedMap(new HashMap<String,SolrServer>());
private EmbeddedServerContainer embeddedServerContainer;


public SolrServer getSearchServer(String searchName){
SolrServer solrServer
= null;
if(!searchServerMap.containsKey(searchName)){
solrServer
= embeddedServerContainer.getSolrCore(searchName);
if(solrServer!=null)
searchServerMap.put(searchName, solrServer);
}
logger.info(
"搜索服务:" + searchName);
return searchServerMap.get(searchName);
}


public EmbeddedServerContainer getEmbeddedServerContainer() {
return embeddedServerContainer;
}


public void setEmbeddedServerContainer(
EmbeddedServerContainer embeddedServerContainer) {
this.embeddedServerContainer = embeddedServerContainer;
}
}

5.定一个EmbeddedServerContainer

package com.sendian.search.solr.server;
import java.io.File;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrResourceLoader;
import org.xml.sax.SAXException;

import com.sendian.search.solr.SearchServerException;

public class EmbeddedServerContainer{
Logger logger
= Logger.getLogger(EmbeddedServerContainer.class);
private static CoreContainer container;
private String searchServerHome;

public EmbeddedServerContainer( String searchServerHome ) throws ParserConfigurationException, IOException, SAXException{
setSearchServerHome(searchServerHome);
File f
= new File( getSearchServerHome(), "search.xml" );
container
= new Initializer().initialize();
container.load(getSearchServerHome(), f);
container.setPersistent(
true);
logger.info(
"启动搜索server完成!");
}

public void shutdown(){
if(container==null)
throw new SearchServerException("不能关闭搜索server,server容器为空!!!");
if(container.isPersistent())
container.persist();
container.shutdown();
logger.info(
"搜索server关闭!");
}

public synchronized void persite(){
if(container==null)
throw new SearchServerException("持久化错误,Server容器不能为空!!!");
container.persist();
logger.info(
"搜索server持久化完成!");
}

public synchronized void addCore(String solrName,String instanceDir,boolean isPersist) throws ParserConfigurationException, IOException, SAXException{
CoreDescriptor p
= new CoreDescriptor(container, solrName, instanceDir);
SolrCore core
= container.create(p);
container.register(solrName, core,
false);
if(isPersist)
container.persist();
}

public SolrServer getSolrCore(String solrName){
if(container.getCoreNames().contains(solrName))
return new EmbeddedSolrServer(container,solrName);
return null;
}


static class Initializer extends CoreContainer.Initializer {
public Initializer(){}
@Override
public CoreContainer initialize() {
return new CoreContainer(new SolrResourceLoader(SolrResourceLoader.locateInstanceDir()));
}

}

public CoreContainer getContainer() {
return container;
}


public String getSearchServerHome() {
return searchServerHome;
}


public void setSearchServerHome(String searchServerHome) {
this.searchServerHome = searchServerHome;
}

}
6.在需要的时候可以通过spring配置下。然后在SolrServer bookserver = searchServerFactory.getSearchServer("book");得到相应的server                      SearchService.java
package com.sendian.subsite.service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Date;

import org.apache.log4j.Logger;
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.SolrRequest.METHOD;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;

import com.sendian.search.solr.SearchServerFactory;
import com.sendian.subsite.entity.FacetBean;
import com.sendian.subsite.entity.DocBean;
import com.sendian.subsite.solr.SolrService;
import com.sendian.subsite.utils.Search;
import com.sendian.subsite.utils.SearchPage;
import com.sendian.utils.DateUtil;
import java.text.SimpleDateFormat;

public class SearchService {

    
private static Logger logger = Logger.getLogger(SearchService.class);
    
private static final String FACETFIELDBOOKCLASS = "csmCode";
    

    
//SolrServer bookserver = SolrServerFactory.getSolrServerInstance();
    private SearchServerFactory searchServerFactory;
    
    
//    SolrServer solrServer = new SolrService().getSolrAdmin();
    

    
public SearchPage getCSE(SolrQuery q, String ccode, int start,
            
int pageSize, boolean isFacet, Locale l) throws SolrServerException, ParseException {
        SolrServer bookserver 
= searchServerFactory.getSearchServer("book");
        SearchPage result 
= null;
        q.setStart(start);
        q.setRows(pageSize);
        QueryRequest r 
= new QueryRequest(q);
        r.setMethod(METHOD.POST);
        logger.debug(
"查询字符:" + q.getQuery());
    
//    System.out.println();
        QueryResponse response = r.process(bookserver);
    
// QueryResponse response = r.process(solrServer);
        List<DocBean> docs = getDocuments(response, l);

        Map m 
= new HashMap();
        m.put(
"docs", docs);
    
//    m.put("facetQuery", getFacetQueryMap(response));
        if (isFacet) {
            List
<FacetBean> bookTypes = getFacetCounts(getFacetMap(response,
                    FACETFIELDBOOKCLASS), ccode);
            m.put(
"clc", bookTypes);
        }
        
return result = new SearchPage(q.getQuery(), response.getQTime(),
                response.getResults().getStart(), response.getResults()
                        .getNumFound(), pageSize, m);
    }

    
public List<DocBean> getDocuments(QueryResponse response, Locale locale) throws ParseException{
        SolrDocumentList l 
= response.getResults();

        List
<DocBean> docbeans = new ArrayList<DocBean>();

        SolrDocument doc 
= null;
        DocBean docbean 
= null;
    
//    SimpleDateFormat aFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
        if (l != null && l.size() > 0) {
            Iterator
<SolrDocument> iter = l.iterator();
            
while (iter.hasNext()) {
                doc 
= iter.next();
                docbean 
= new DocBean();
                docbean.setAutherName(doc.getFieldValue(
"autherName"!=null?doc.getFieldValue("autherName").toString():"");
                docbean.setBookId(doc.getFieldValue(
"bookId"!=null?doc.getFieldValue("bookId").toString():"");
                docbean.setBookBrief(doc.getFieldValue(
"bookBrief"!=null?doc.getFieldValue("bookBrief").toString():"");
                docbean.setPubDate(doc.getFieldValue("pubDate"!=null?((String)(doc.getFieldValue("pubDate"))):null);
                docbean.setCsmCode(doc.getFieldValue(
"csmCode"!=null?doc.getFieldValue("csmCode").toString():"");
                docbean.setPublishName(doc.getFieldValue(
"publishName"!=null?doc.getFieldValue("publishName").toString():"");
                docbean.setBookCover(doc.getFieldValue(
"bookCover"!=null?doc.getFieldValue("bookCover").toString():"");
                docbean.setClcCode(doc.getFieldValue(
"clcCode"!=null?doc.getFieldValue("clcCode").toString():"");
                docbean.setUpperName(doc.getFieldValue(
"upperName"!=null?doc.getFieldValue("upperName").toString():"");
                docbean.setAuthers(doc.getFieldValue(
"authors"!=null?doc.getFieldValue("authors").toString():"");
                docbean.setBookStatus(doc.getFieldValue(
"bookStatus"!=null?doc.getFieldValue("bookStatus").toString():"");
                docbean.setBookName(doc.getFieldValue(
"bookName"!=null?doc.getFieldValue("bookName").toString():"");
                docbean.setBookPrice(doc.getFieldValue(
"bookPrice"!=null?doc.getFieldValue("bookPrice").toString():"");
                docbean.setIsbn(doc.getFieldValue(
"isbn"!=null?doc.getFieldValue("isbn").toString():"");
                docbeans.add(docbean);
            }
        }
        
return docbeans;
    }

    
public DocBean findDocById(String docId, Locale locale)
            
throws SolrServerException, ParseException {
        SolrServer bookserver 
= searchServerFactory.getSearchServer("book");
        DocBean docbean 
= null;
        SolrQuery q 
= new SolrQuery();
        QueryRequest r 
= new QueryRequest(q);
        q.setQuery(
"bookId:\"" + docId + '"');
        r.setMethod(METHOD.POST);
        QueryResponse response 
= r.process(bookserver);
        List
<DocBean> l = this.getDocuments(response, locale);
        
if (l.size() > 0)
            
return l.get(0);
        
return docbean;
    }
    
    
public Map<String, Long> getFacetMap(QueryResponse response, String facet) {
        Map
<String, Long> map = new HashMap<String, Long>();
        
if (response.getFacetField(facet) == null)
            
return map;
        List
<Count> l = response.getFacetField(facet).getValues();
        
if (l != null && l.size() > 0) {
            Iterator
<Count> iter = l.iterator();
            
while (iter.hasNext()) {
                Count c 
= iter.next();
                map.put(c.getName(), c.getCount());
            }
        }

        
return map;
    }
    
    
public List<FacetBean> getFacetCounts(Map<String, Long> map, String ccode) {
    
//    Search search = new Search();
        FacetBean facet = null;
        List
<FacetBean> l = new ArrayList<FacetBean>();
        
// Map<String,Integer> resultsmap = new HashMap<String,Integer>();
        int length = 0;
        
if (ccode == null || ccode.length() < 3) {
            length 
= 3;
        } 
else {
            length 
= ccode.length() + 3;
            
// resultsmap.put("current",map.get(ccode));
        }

        Set
<CcodeObject> set = new HashSet<CcodeObject>();
        getSubFacetSet(set, map, length);
        Iterator
<CcodeObject> iterSet = set.iterator();
        
while (iterSet.hasNext()) {
            String keyccode 
= iterSet.next().getCcode();
            
// System.out.println("+"+keyccode);
            facet = new FacetBean();
            facet.setName(Search.getAttribute(keyccode).toString());
            facet.setCount(sunCounts(map, keyccode));
            facet.setId(keyccode);
            l.add(facet);
            
/*
             * if(l.size()>9) break;
             
*/

            
// resultsmap.put(keyccode,sunCounts(map,keyccode));
        }
        
if (l.size() < 1 && (ccode != null && ccode.trim().length() > 0)) {
            facet 
= new FacetBean();
            facet.setName(Search.getAttribute(ccode).toString());
            facet.setCount(sunCounts(map, ccode));
            facet.setId(ccode);
            l.add(facet);
        }
        Collections.sort(l);
        
return l;

}
    
    
private Map<String, Integer> getFacetQueryMap(QueryResponse response) {
        Map
<String, Integer> map = new HashMap<String, Integer>();
        map 
= response.getFacetQuery();
        
return map;
    }
    
    
private Long sunCounts(Map<String, Long> map, String ccode) {
        
int i = 0;
        Iterator
<Map.Entry<String, Long>> itermap = map.entrySet().iterator();
        
while (itermap.hasNext()) {
            Map.Entry
<String, Long> me = itermap.next();
            String key 
= me.getKey();
            Long value 
= me.getValue();
            
if (key.startsWith(ccode))
                i 
= i + value.intValue();
        }
        
return new Long(i);
    }
    
    
public void getSubFacetSet(Set<CcodeObject> set, Map<String, Long> map,
            
int i) {
        Iterator
<String> keySet = map.keySet().iterator();
        
while (keySet.hasNext()) {
            String key 
= keySet.next();
            
if (key.length() >= i) {
                CcodeObject c 
= new CcodeObject();
                c.setCcode(key.substring(
0, i));
                set.add(c);
            }
        }
    }
    
    
class CcodeObject {
        
private String ccode;

        @Override
        
public boolean equals(Object o) {
            
if (o == null)
                
return false;
            CcodeObject os 
= (CcodeObject) o;
            
if (this.ccode.equals(os))
                
return true;
            
if (os.getCcode().startsWith(this.ccode))
                
return true;
            
if (this.ccode.length() > os.getCcode().length()
                    
&& this.ccode.startsWith(os.getCcode())) {
                
this.ccode = os.getCcode();
                
return true;
            } 
else {
                
return false;
            }
        }

        @Override
        
public int hashCode() {
            
// TODO 自动生成方法存根
            return BigDecimal.ROUND_CEILING;
        }

        
public String getCcode() {
            
return this.ccode;
        }

        
public void setCcode(String ccode) {
            
this.ccode = ccode;
        }
    }
/*    public static Date dateFormat(Date d){
        
        Date d =new Date(date);
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
        return sd.format(d);
        
    }
*/

    
public SearchServerFactory getSearchServerFactory() {
        
return searchServerFactory;
    }

    
public void setSearchServerFactory(SearchServerFactory searchServerFactory) {
        
this.searchServerFactory = searchServerFactory;
    }
}

posted on 2008-09-09 11:32 anoic 阅读(3189) 评论(1)  编辑  收藏

评论

# re: Solr 嵌入式开发 2009-03-10 17:24 村民

哥们,还有几个类没有? 主要是SearchPage,FacetBean,Count这几个.能否发上来或发邮件27468001@qq.com  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

导航

<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

统计

常用链接

留言簿(3)

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜