solr3.5集成paoding和位置搜索及对solrj的使用。

http://xiaofancn.iteye.com/blog/1424252

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

http://hi.baidu.com/channing07/blog/item/cb840754a98fc7c9b645ae3e.html

 * https://github.com/dsmiley/SOLR-2155 关于位置的搜索的增强库

 * http://wiki.apache.org/solr/SpatialSearch#SOLR-2155

为了让paoding适合高版本的solr3.5,我重新更换了一下paoding编译的部分jar包。


jar是从 solr3.5 项目中apache-tomcat-7.0.27\webapps\solr\WEB-INF\lib复制

添加新的分词类

package net.paoding.analysis.analyzer.solr;
import java.io.Reader;
import java.util.Map;
import net.paoding.analysis.analyzer.PaodingTokenizer;
import net.paoding.analysis.analyzer.TokenCollector;
import net.paoding.analysis.analyzer.impl.MaxWordLengthTokenCollector;
import net.paoding.analysis.analyzer.impl.MostWordsTokenCollector;
import net.paoding.analysis.knife.PaodingMaker;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.solr.analysis.BaseTokenizerFactory;

public class ChineseTokenizerFactory  extends BaseTokenizerFactory {
	/**
	* 最多切分 默认模式
	*/
	public static final String MOST_WORDS_MODE = "most-words";
	/**
	* 按最大切分
	*/
	public static final String MAX_WORD_LENGTH_MODE = "max-word-length";
	private String mode = null;

	public void setMode(String mode) {
	   if (mode == null || MOST_WORDS_MODE.equalsIgnoreCase(mode)
	     || "default".equalsIgnoreCase(mode)) {
	    this.mode = MOST_WORDS_MODE;
	   } else if (MAX_WORD_LENGTH_MODE.equalsIgnoreCase(mode)) {
	    this.mode = MAX_WORD_LENGTH_MODE;
	   } else {
	    throw new IllegalArgumentException(
	      "不合法的分析器Mode                                                参数设置:"
	        + mode);
	   }
	}

	@Override
	public void init(Map<String,String> args) {
	   super.init(args);
	   setMode(args.get("mode"));
	}

	public Tokenizer create(Reader input) {
	   return new PaodingTokenizer(input, PaodingMaker.make(),
	     createTokenCollector());
	}

	private TokenCollector createTokenCollector() {
	   if (MOST_WORDS_MODE.equals(mode))
	    return new MostWordsTokenCollector();
	   if (MAX_WORD_LENGTH_MODE.equals(mode))
	    return new MaxWordLengthTokenCollector();
	   throw new Error("never happened");
	}
}

编译后,复制paoding-analysis.jar到solr的lib包中

apache-tomcat-7.0.27\webapps\solr\WEB-INF\lib

apache-tomcat-7.0.27\webapps\solr\solr\conf\schema.xml

里面很多field的type是text_general

所以我们修改text_general类型的切词类,

将类型text_general中的

索引查询的切词类,换成我们的切词类。

<tokenizer class="net.paoding.analysis.analyzer.solr.ChineseTokenizerFactory" mode="most-words"/> 

起动tomcat,成功后。

在我们的maven,pom.xml文件中添加solrj

<dependency>
               <artifactId>solr-solrj</artifactId>
               <groupId>org.apache.solr</groupId>
               <version>1.3.0</version>
               <type>jar</type>
               <scope>test</scope>
        </dependency>
        <dependency>
               <artifactId>solr-core</artifactId>
               <groupId>org.apache.solr</groupId>
               <version>1.3.0</version>
               <type>jar</type>
               <scope>test</scope>
        </dependency>
 

测试代码,运行前请读下面的注意事项。

package com.snailteam.team.dao;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest.METHOD;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.snailteam.team.model.City;
import com.snailteam.team.model.Shop;
import com.snailteam.team.service.CityService;
import com.snailteam.team.service.ProductService;
import com.snailteam.team.service.ShopService;
import com.snailteam.team.service.UserService;

/**
 * 
 * https://github.com/dsmiley/SOLR-2155
 * http://wiki.apache.org/solr/SpatialSearch#SOLR-2155
 * 
 * 
 * @author fansxnet
 * 
 */

@SuppressWarnings("restriction")
@ContextConfiguration(locations = { "classpath*:/META-INF/spring/applicationContext*.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class UserServiceTest {

	public static String url = "http://localhost:8080/solr/";
	public static CommonsHttpSolrServer server;

	@Before
	public void before() throws MalformedURLException {
		server = new CommonsHttpSolrServer(url);
		server.setParser(new XMLResponseParser());

	}

	@Resource
	public UserService userService;

	@PersistenceContext
	EntityManager em;

	@Resource
	ShopService shopService;

	@Resource
	CityService cityService;

	@Resource
	ProductService productService;

	@Resource
	MongoTemplate mongoTemplate;

	@Test
	public void testTorecallAdIdList() {

	}

	@Test
	public void testSoleAdd() throws SolrServerException, IOException {
		City city = cityService.getAll().get(0);
		List<Shop> shops = shopService.getShops(city);
		Collection<SolrInputDocument> docs = new HashSet<SolrInputDocument>();
		for (Shop shop : shops) {
			SolrInputDocument doc = new SolrInputDocument();
			doc.addField("id", shop.getId());
			if (shop.getLatitude() != null && shop.getLongitude() != null) {
				// latitudes are range -90 to 90
				// longitude are range -180 to 180
				// doc.addField("loc",
				// shop.getLongitude() + "," + shop.getLatitude());
				doc.addField("shopname", shop.getName());
				doc.addField("addr", shop.getAddr());
				doc.addField("tel", shop.getTel());
				doc.addField("traff", shop.getTraff());
				doc.addField("shoploc",
						shop.getLatitude() + "," + shop.getLongitude());
			}
			docs.add(doc);

		}
		server.add(docs);
		server.commit();

	}

	/**
	 * 暂时不可用
	 * 
	 * @throws SolrServerException
	 * @throws IOException
	 */
	@Test
	public void testSoleSearch() throws SolrServerException, IOException {
		// //
		// select?wt=json&indent=true&fl=shopname,addr,tel,traff,shoploc,_dist_:geodist()&q=*:*&sfield=store&pt=39.904392,116.265033&sort=geodist()%20asc
		SolrQuery query = new SolrQuery();
		query.setQuery("shopname:北京");// &q=*:*
		query.setFacet(true);
		query.setFacetMinCount(1);
		query.setFacetLimit(8);
		// 参数说明
		// indent – 返回的结果是否缩进,默认关闭,
		// fl – 返回的字段
		// sfield – spatial point data is "sfield". See the console output
		// below.
		// pt – latitude longitude
		// sort 排序字段 geodist()%20asc 有问题
		// ,_dist_:geodist()获取距离不正确,无值

		query.set("sfield", "store");//
		query.set("pt", "39.904392,116.265033");
		query.set("sort", "geodist() asc");
		query.set("fl", "_dist_:geodist()");

		query.setFields("shopname", "addr", "tel", "traff", "shoploc");
		server.setParser(new XMLResponseParser());// 设置solrj的解析格式
		QueryResponse rsp = server.query(query, METHOD.POST);
		SolrDocumentList docs = rsp.getResults();
		Iterator<SolrDocument> iterator = docs.iterator();
		while (iterator.hasNext()) {
			SolrDocument solrDoc = iterator.next();
			System.out.println(solrDoc.getFieldValue("shopname") + "-"
					+ solrDoc.getFieldValue("addr") + "-"
					+ solrDoc.getFieldValue("shoploc") + "-");
		}
	}
}

 

注意:

为了更形象,我们在solr中定义与我们项目一致的feild字段。新加

<!--shop field-->
		
		<field name="shopid" type="text_general" indexed="true" stored="true"/>
		<field name="shopname" type="text_general" indexed="true" stored="true"/>
		<field name="addr" type="text_general" indexed="true" stored="true"/>
		<field name="tel" type="text_general" indexed="true" stored="true"/>
		<field name="traff" type="text_general" indexed="true" stored="true"/>
		<field name="shoploc" type="location" indexed="true" stored="true" /> 
 

打开solr后台管理页面 http://localhost:8080/solr/admin/

search

shopid:3153

猜你喜欢

转载自xiaofancn.iteye.com/blog/1502726