Solr入门和实践以及我对Solr的8点理解

友情提示
Solr的内容还是比较多的,一篇文章只能讲解一部分。
全面介绍,没兴趣,没时间,也没能力,回报还不大。
本文只写点我认为比较重要的知识点,独特的个人想法。
仅供参考哦,更多细节需要自己去琢磨。

概述
Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,
同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。

工作方式
文档通过Http利用XML 加到一个搜索集合中。
查询该集合也是通过http收到一个XML/JSON响应来实现。
它的主要特性包括:高效、灵活的缓存功能,垂直搜索功能,高亮显示搜索结果,通过索引复制来提高可用性,
提供一套强大Data Schema来定义字段,类型和设置文本分析,提供基于Web的管理界面等。

需求场景
  查询和搜索,我们直接查询数据库MySQL。查询数据库主要有一些局限性:
比如多表查询效率低,大文本字段不好建立索引和搜索,复杂的条件查询和搜索功能不够强大,或者说不够简单。
  使用Solr的话,就很简单地解决了以上问题。
  
  以上需求,或者说关系型数据库mysql的问题,只是目前的一点理解。
  虽说能够使用MySQL和Sorl解决实际中的问题,但毕竟都是中低难度的问题(自认为如此哦)。
  非要说深入理解,剖析Solr的好处,MySQL是否“干的过”Solr,真心不懂。
  单独搞MySQL,够你研究5年以上,DBA毕竟是个传说。
  Solr,想搞懂,也得好多年。
  
  个人同时学习Java服务端、Android、iOS、Web前端,目标是能够解决工作中最常见的问题,并不想要
深入学习有限的几种技术,比如MySQL,达到那种“再难的问题,也可以搞定”的程度。

我对Solr的8点理解
1.定义数据源接口,获得数据。

  比如定义MySQL查询语句,把一个表或多个表的数据,导入到Solr中。
  这个地方我觉得特别“不公平”,数据都是从别的地方搞过来的。外界的数据如果会变化,意味着,必须处理“数据同步”。
  实时性要求不高的情况下,可以每天“全量更新”。要求高的情况下,单条数据的变化,需要“实时更新-单条”。
  因此,Solr和Mysql并不是“直接竞争”关系,而是“互补”的关系。
2.把Mysql等数据源的数据,导入到Solr中去。
  Solr定义数据,可以理解成一张很大的表,包含了很多字段,比如可以包含mysql中3个表的所有字段。
  这样,查询就不存在“多表”的问题。
  既然是一张表,建立索引,查询就很快了。
3.自带缓存功能。
  Mysql,Solr,Redis等数据源或者有能力获得数据和管理数据的组件,只要需要,就可以提供“缓存”功能。
  Solr简化了查询,缓存就更容易了。
4.索引和全文搜索。
  Solr底层采用Lucene建立索引,全文索引,这样可以实现更多的“搜索功能”,可以说增强了Mysql的查询。
5.站内搜索的另外一种形式。
  百度等搜索引擎,可以为网站提供“站内搜索”功能,他们爬去数据可以是公开的URL的形式。
  如果需要和百度等合作,可以申请使用百度的搜索API,将站内数据,更友好,更快速地告诉百度。
  而Solr和百度提供的搜索相关接口就基本一样,只不过是处在我们的管理之下。
6.简洁使用的管理界面。
  后台有Web界面,导入数据,更新,可以通过可视化的操作来管理,比较方便。
7.功能服务化。
  Solr提供的查询等功能,有Java等多种语言的实现。
  建立数据结构,导入数据,维护缓存和实时性,最重要的就是“查询”和“搜索”了。
8.最大的“隐患”。
  只用Mysql管理数据和查询的时候,我们必须并且只需要保障mysql的“高可用性”。
  不能出任何问题,如果只用1个Mysql,意味着我们需要实时监控Mysql是否可用,如果出了问题,我们需要立即修复它。
  如果是多台Mysql,我们需要用主从,或者更复杂的主从。
  
  现在用了Solr,意味着,我们很多查询和搜索,优先使用Solr,不再使用Mysql。
  这个时候,为了“高可靠性”,我们也必须保障Solr是靠谱的。
  单台Solr服务器,可靠性怎么样,我不太清楚。
  无论单台Solr是否靠谱,多台Solr更加靠谱,这都意味着
  “我们程序中必须可靠的基础服务更多了”。
  
  常见的必须“高可用性”的服务有
  a.Mysql
  b.Redis
  3.Nginx
  4.Solr
  高可用性的服务越多,意味着我们的程序越复杂。
  大部分的公司,都是中小型企业。
  大部分的应用,都是为了快速推出,看看是否有效果。
  真正需要保障“高可靠性”的项目,是很少的,如果遇到了,是很幸运的。
  
 官方网站:http://lucene.apache.org/solr/
 本地环境:Windows-5.3.1版本
 
 运行和建立工程
 启动:solr.cmd start(类似这样)
 建立工程:
name=raikou
config=solrconfig.xml
schema=schema.xml
dataDir=J\:\\SoftData\\Solr\\raikou\\data
指定config、schema等多种参数。
(图文并茂的入门指引,可以参考其它博主的文章,本人觉得这种“图文并茂”的太尼玛费事了。
方便了读者,但是“技术含量”不够高,博主表示不过瘾o(︶︿︶)o )

简要介绍下几个配置,附带源文件内容

core.properties

name=raikou(项目名称)
config=solrconfig.xml(Solr配置)
schema=schema.xml(模式定义)
dataDir=J\:\\SoftData\\Solr\\raikou\\data (存储索引等数据)

Web界面输入的内容,保存在这了,入口配置,可以这么说。

schema.xml

   <field name="id" type="long" indexed="true" stored="true" required="true" multiValued="false" />
   <field name="title" type="string" indexed="true" stored="true" required="true" />
   <field name="content" type="string" indexed="true" stored="true" />
   <field name="summary" type="string" indexed="true" stored="true" /> 

定义了几个字段

<uniqueKey>id</uniqueKey>
 <defaultSearchField>title</defaultSearchField>
  唯一字段,默认查询字段
  
  schemal.xml还配置了若干其它配置文件,比如“stopwords_en.txt”、“protwords.txt”、“stopwords.txt”等。
  如果Solr启动报错,可能是缺少了这些字段。
 
data-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<dataConfig>
<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/raikou?useUnicode=true&characterEncoding=UTF-8"
    user="root"
    password="mypassword"/>  

<document name="raikou_article">
    <entity name="raikou_article"
	query="select * from raikou_article"
	deltaImportQuery="select * from raikou_article where id=‘${dih.delta.id}‘"
	deltaQuery="select * from raikou_article where update_time > ‘${dataimporter.last_index_time}‘">
                <field column="id"						name="id"      />
                <field column="title"			name="title"      />
				 <field column="content"			name="content"      />
				  <field column="summary"			name="summary"      />
    </entity>
</document>
</dataConfig>  

定义了数据导入、增量更新的查询语句。
  
 web.xml 这段配置,可能有用
  E:\Mongodb-Redis-Nginx\solr-5.3.1\server\solr-webapp\webapp\WEB-INF\web.xml

 <!-- People who want to hardcode their "Solr Home" directly into the
       WAR File can set the JNDI property here...
   -->

    <env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>J:\SoftData\Solr\</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>

Java程序访问
  maven配置

<dependency>
		<groupId>org.apache.solr</groupId>
		<artifactId>solr-solrj</artifactId>
		<version>5.3.1</version>
	</dependency>

包名:org.apache.solr.client.solrj

工具类
SolrHelper.java 查询(查询语句构造和执行查询,分页查询),更新,重建索引

import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrInputDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.pagehelper.Page;

/**查询(查询语句构造),更新,重建索引*/
public class SolrHelper<T> {

	protected final Logger logger = LoggerFactory.getLogger(SolrHelper.class);

	private HttpSolrClient server;

	private StringBuffer queryString;

	public SolrHelper(String reqUrl) {
		server = new HttpSolrClient(reqUrl);
		queryString = new StringBuffer();
	}

	public void andEquals(String fieldName, String val) {
		queryString.append(" && ").append(fieldName).append(":").append(val);
	}

	public void orEquals(String fieldName, String val) {
		queryString.append(" || ").append(fieldName).append(":").append(val);
	}

	public void andNotEquals(String fieldName, String val) {
		queryString.append(" && ").append("-").append(fieldName).append(":")
				.append(val);
	}

	public void orNotEquals(String fieldName, String val) {
		queryString.append(" || ").append("-").append(fieldName).append(":")
				.append(val);
	}

	public void andGreaterThan(String fieldName, String val) {
		queryString.append(" && ").append(fieldName).append(":[").append(val)
				.append(" TO ").append("*]");
	}

	public void orGreaterThan(String fieldName, String val) {
		queryString.append(" || ").append(fieldName).append(":[").append(val)
				.append(" TO ").append("*]");
	}

	public void andGreaterThanOrEqualTo(String fieldName, String val) {
		queryString.append(" && ").append(fieldName).append(":[").append(val)
				.append(" TO ").append("*]");
	}

	public void orGreaterThanOrEqualTo(String fieldName, String val) {
		queryString.append(" || ").append(fieldName).append(":[").append(val)
				.append(" TO ").append("*]");
	}

	public void andDateGreaterThan(String fieldName, Date val) {
		queryString.append(" && ").append(fieldName).append(":[")
				.append(formatUTCString(val)).append(" TO ").append("*]");
	}

	public void orDateGreaterThan(String fieldName, Date val) {
		queryString.append(" || ").append(fieldName).append(":[")
				.append(formatUTCString(val)).append(" TO ").append("*]");
	}

	public void andDateGreaterThanOrEqualTo(String fieldName, Date val) {
		queryString.append(" && ").append(fieldName).append(":[")
				.append(formatUTCString(val)).append(" TO ").append("*]");
	}

	public void orDateGreaterThanOrEqualTo(String fieldName, Date val) {
		queryString.append(" || ").append(fieldName).append(":[")
				.append(formatUTCString(val)).append(" TO ").append("*]");
	}

	public void andLessThan(String fieldName, String val) {
		queryString.append(" && ").append(fieldName).append(":[").append("*")
				.append(" TO ").append(val).append("]");
	}

	public void orLessThan(String fieldName, String val) {
		queryString.append(" && ").append(fieldName).append(":[").append("*")
				.append(" TO ").append(val).append("]");
	}

	public void andLessThanOrEqualTo(String fieldName, String val) {
		queryString.append(" && ").append(fieldName).append(":[").append("*")
				.append(" TO ").append(val).append("]");
	}

	public void orLessThanOrEqualTo(String fieldName, String val) {
		queryString.append(" && ").append(fieldName).append(":[").append("*")
				.append(" TO ").append(val).append("]");
	}

	public void andDateLessThan(String fieldName, Date val) {
		queryString.append(" && ").append(fieldName).append(":[").append("*")
				.append(" TO ").append(formatUTCString(val)).append("]");
	}

	public void orDateLessThan(String fieldName, Date val) {
		queryString.append(" && ").append(fieldName).append(":[").append("*")
				.append(" TO ").append(formatUTCString(val)).append("]");
	}

	public void andDateLessThanOrEqualTo(String fieldName, Date val) {
		queryString.append(" && ").append(fieldName).append(":[").append("*")
				.append(" TO ").append(formatUTCString(val)).append("]");
	}

	public void orDateLessThanOrEqualTo(String fieldName, Date val) {
		queryString.append(" && ").append(fieldName).append(":[").append("*")
				.append(" TO ").append(formatUTCString(val)).append("]");
	}

	public void andLike(String fieldName, String val) {
		queryString.append(" && ").append(fieldName).append(":*").append(val)
				.append("*");
	}

	public void orLike(String fieldName, String val) {
		queryString.append(" || ").append(fieldName).append(":*").append(val)
				.append("*");
	}

	public void andNotLike(String fieldName, String val) {
		queryString.append(" && ").append("-").append(fieldName).append(":*")
				.append(val).append("*");
	}

	public void orNotLike(String fieldName, String val) {
		queryString.append(" || ").append("-").append(fieldName).append(":*")
				.append(val).append("*");
	}

	public void andIn(String fieldName, String[] vals) {
		queryString.append(" && ");
		in(fieldName, vals);
	}
	private void in(String fieldName, String[] vals) {
		List<String> list=Arrays.asList(vals);
		in(queryString,fieldName,list);
	}

	public void orIn(String fieldName, List<String> vals) {
		queryString.append(" || ");
		in(queryString,fieldName,vals);
	}

	private static void in(StringBuffer queryString,String fieldName, List<String> vals) {
		queryString.append("(");
		inStr(queryString, fieldName, vals);
		queryString.append(")");
	}

	private static void inStr(StringBuffer queryString, String fieldName,
			List<String> vals) {
		int index = 0;
		for (String val : vals) {
			if (0 != index) {
				queryString.append(" || ");
			}
			queryString.append(fieldName).append(":").append(val);
			index++;
		}
	}

	// http://stackoverflow.com/questions/634765/using-or-and-not-in-solr-query
	//instead of "NOT [condition]" use "(*:* NOT [condition])"
	public void andNotIn(String fieldName, String[] vals) {
		List<String> list=Arrays.asList(vals);
		queryString.append("&&(");
		queryString.append("*:* NOT ");
		inStr(queryString, fieldName, list);
		queryString.append(")");
	}

	public void andDateBetween(String fieldName, Date startDate, Date endDate) {
		queryString.append(" && ").append(fieldName).append(":[")
				.append(formatUTCString(startDate)).append(" TO ")
				.append(formatUTCString(endDate)).append("]");
	}

	public void orDateBetween(String fieldName, Date startDate, Date endDate) {
		queryString.append(" || ").append(fieldName).append(":[")
				.append(formatUTCString(startDate)).append(" TO ")
				.append(formatUTCString(endDate)).append("]");
	}

	public void andDateNotBetween(String fieldName, Date startDate, Date endDate) {
		queryString.append(" && ").append("-").append(fieldName).append(":[")
				.append(formatUTCString(startDate)).append(" TO ")
				.append(formatUTCString(endDate)).append("]");
	}

	public void orDateNotBetween(String fieldName, Date startDate, Date endDate) {
		queryString.append(" && ").append("-").append(fieldName).append(":[")
				.append(formatUTCString(startDate)).append(" TO ")
				.append(formatUTCString(endDate)).append("]");
	}

	public void andBetween(String fieldName, String start, String end) {
		queryString.append(" && ").append(fieldName).append(":[").append(start)
				.append(" TO ").append(end).append("]");
	}

	public void orBetween(String fieldName, String start, String end) {
		queryString.append(" || ").append(fieldName).append(":[").append(start)
				.append(" TO ").append(end).append("]");
	}

	public void andNotBetween(String fieldName, String start, String end) {
		queryString.append(" && ").append("-").append(fieldName).append(":[")
				.append(start).append(" TO ").append(end).append("]");
	}

	public void orNotBetween(String fieldName, String start, String end) {
		queryString.append(" || ").append("-").append(fieldName).append(":[")
				.append(start).append(" TO ").append(end).append("]");
	}

	public void andStartSub() {
		queryString.append(" && (");
	}

	public void orStartSub() {
		queryString.append(" || (");
	}

	public void endSub() {
		queryString.append(")");
	}

	private String formatUTCString(Date d) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd‘T‘HH:mm:ss‘Z‘");
		String s = sdf.format(d);
		return s;
	}

	public int execQueryTotalCount() {
		SolrQuery params = handleQuery();
		params.set("start", 0);
		params.set("rows", Integer.MAX_VALUE);
		QueryResponse response = null;
		try {
			response = server.query(params);
			return response.getResults().size();
		} catch (SolrServerException e) {
			logger.error("", e);
		} catch (IOException e) {
			logger.error("", e);
		}

		return 0;
	}

	public List<T> query(String sort, Class<T> beanClass) {
		SolrQuery params = handleQuery();
		QueryResponse response = null;
		List<T> list = null;
		try {
			logger.info("SolyQuery:" + params.toString());
			response = server.query(params);
			list = (List<T>) response.getBeans(beanClass);
		} catch (SolrServerException e) {
			logger.error("SolrServerException", e);
		} catch (IOException e) {
			logger.error("IOException", e);
		}
		return list;
	}

	public Page<T> execQuery(Integer pageNo, Integer rows, String sort,
			Class<T> beanClass) {
		List<T> results = null;
		Page<T> page = null;
		SolrQuery params = handleQuery();
		if (pageNo != null && rows != null && pageNo > 0 && rows > 0) {
			params.set("start", (pageNo - 1) * rows);
			params.set("rows", rows);
		}
		if (null != sort && !"".equals(sort)) {
			params.set("sort", sort);
		}

		QueryResponse response = null;
		try {
			logger.info("SolyQuery WithPage:" + params.toString());
			response = server.query(params);
			results = (List<T>) response.getBeans(beanClass);
			page = new Page<T>(pageNo, rows, execQueryTotalCount());
			page.addAll(results);
		} catch (SolrServerException e) {
			logger.error("SolrServerException", e);
		} catch (IOException e) {
			logger.error("IOException", e);
		}

		return page;

	}

	private SolrQuery handleQuery() {
		SolrQuery params = new SolrQuery();
		String qryFinalStr = queryString.toString();
		if (qryFinalStr.startsWith(" && ")) {
			qryFinalStr = qryFinalStr.replaceFirst(" && ", "");
		} else if (qryFinalStr.startsWith(" || ")) {
			qryFinalStr = qryFinalStr.replaceFirst(" || ", "");
		}
		// 子查询开头的关联符号
		if (-1 != qryFinalStr.indexOf("( && ")) {
			qryFinalStr = qryFinalStr.replaceAll("\\( \\&\\& ", "(");
		}

		if (-1 != qryFinalStr.indexOf("( || ")) {
			qryFinalStr = qryFinalStr.replaceAll("\\( \\|\\| ", "(");
		}

		if (StringUtils.isBlank(qryFinalStr)) {
			qryFinalStr = "*:*";
		}

		params.set("q", qryFinalStr);
		return params;
	}

	public void execDelete(String keyName, String keyVal) {
		try {
			server.deleteByQuery(keyName + ":" + keyVal);
			server.commit();
		} catch (SolrServerException | IOException e) {
			logger.error("", e);
		}
	}

	public void execUpdate(T model) {
		Field[] fields = model.getClass().getDeclaredFields();
		SolrInputDocument solrDoc = new SolrInputDocument();
		try {
			for (Field f : fields) {
				PropertyDescriptor pd;
				pd = new PropertyDescriptor(f.getName(), model.getClass());
				// 属性名
				String fieldName = f.getName();
				Method rM = pd.getReadMethod();// 获得读方法
				solrDoc.addField(fieldName, rM.invoke(model));
			}
			server.add(solrDoc);
			server.commit();
		} catch (Exception e) {
			logger.error("", e);
		}
	}

	public void execUpdate(SolrInputDocument solrDoc) {
		try {
			server.add(solrDoc);
			server.commit();
		} catch (SolrServerException e) {
			logger.error("", e);
		} catch (IOException e) {
			logger.error("", e);
		}
	}

	/**
	 * 重建索引和增量索引的接口
	 *
	 * @param delta
	 */
	public void buildIndex(boolean delta) {
		SolrQuery query = new SolrQuery();
		// 指定RequestHandler,默认使用/select
		query.setRequestHandler("/dataimport");

		String command = delta ? "delta-import" : "full-import";
		String clean = delta ? "false" : "true";
		String optimize = delta ? "false" : "true";

		query.setParam("command", command).setParam("clean", clean)
				.setParam("commit", "true").setParam("optimize", optimize);
		try {
			server.query(query);
		} catch (SolrServerException e) {
			logger.error("建立索引时遇到错误,delta:" + delta, e);
		} catch (IOException e) {
			logger.error("建立索引时遇到错误,delta:" + delta, e);

		}
	}
}

代码使用示例:
    1.常见的分页查询,更新单条数据

public static void main(String[] args) {
		SolrHelper<Project> sh = new SolrHelper<Project>(
				"http://host/solr/project");
		sh.andEquals("id", "32404");
		List<Project> page = sh.execQuery(1, 10, "id desc",
				Project.class);
		Project ps = page.get(0);
		ps.setTotal(3.1415);
		sh.execUpdate(ps);
	}

2.不修改,直接同步

public void synProject(long id) {
		ProjectSolrDto solrDto = projectMapper.selectSolrProjectSimple(id);
		SolrHelper<ProjectSolrDto> solrHelper = new SolrHelper<ProjectSolrDto>(
				solrProjectUrl);
		solrHelper.execUpdate(solrDto);
	}

3.同步某几个字段

public void synIntention(Long id) {
		Intention intention = intentionMapper.selectByPrimaryKey(id);
		SolrHelper<Intention> solrHelper = new SolrHelper<Intention>(
				solrIntentionUrl);
		SolrInputDocument solrDoc = new SolrInputDocument();
		solrDoc.addField("id", intention.getId());
		solrDoc.addField("intro", intention.getIntro());
		solrDoc.addField("industry", intention.getIndustry());
		solrHelper.execUpdate(solrDoc);
	}
	

4.删除

public void delFund(Long id) {
		SolrHelper<Intention> solrHelper = new SolrHelper<Intention>(
				solrFundUrl);
		solrHelper.execDelete("id", id.toString());
	}

几点补充
1.需要有“定时器”,定时“全量更新”和“重建索引”,防止数据不一致,或者查询效率低。
2.SolrHelper中的代码,或者说Solr的相关代码,无非就是“增删改查CRUD”,比较特殊的
“重建索引”和为了执行查询,拼接查询条件的“And,Or”等工具方法。
3.分页有个实体类,用到了Github上的1个工具,个人觉得一般般,Page类的定义比较糟糕。
如有需要,自己引入,或者自行改造。

写在最后
IT互联网技术很多,更新很快,问题也很多,深入需要实践,深入需要时间。
技术方面的博学和专注,自己去平衡吧~
技术和技术之外的平衡,自己看着办哦~

更多资料
Solr 搭建搜索服务器
http://my.oschina.net/u/1757458/blog/389109?fromerr=HUEucn9b

Solr调研总结
http://www.cnblogs.com/guozk/p/3498831.html

Solr中国
http://www.solr.cc/blog/

solr对跨服务器表联合查询的配置
http://blog.csdn.net/awj3584/article/details/10326439

时间: 2024-10-13 05:15:51

Solr入门和实践以及我对Solr的8点理解的相关文章

solr入门之solr安全控制的研究和实践(二)

Permission Attributes(权限属性) 每个用户又一个或者几个权限组成,每个权限由几个定义过可以做哪些事的属性组成. 下面有一些不能被修改的预定义权限: Pre-defined Permissions 有一些预定义的权限.这些固定的默认值,不能修改,无法添加新属性.要使用这些属性,只需定义一个角色,包括这个权限, 然后给一个用户分配角色. security-edit: 该许可允许编辑安全配置,这意味着任何更新的操作修改security.json 通过api将被允许. securi

solr入门教程

Solr 本文介绍solr的功能使用及相关注意事项;主要包括以下内容:环境搭建及调试;两个核心配置文件介绍;维护索引;查询索引,和在查询中可以应用的高亮显示.拼写检查.搜索建议.分组统计.拼音检索等功能的使用方法. 1. Solr 是什么? Solr它是一种开放源码的.基于 Lucene Java 的搜索服务器,易于加入到 Web 应用程序中.Solr 提供了层面搜索(就是统计).命中醒目显示并且支持多种输出格式(包括XML/XSLT 和JSON等格式).它易于安装和配置,而且附带了一个基于HT

solr入门之多线程操作solr中索引字段的解决

涉及的问题: 建索引时有一个字段是该词语出现的次数,这个字段是放在solr里的 而我用的是多线程来进行全量导入的,这里就涉及到了多线程问题 多个线程操作同一个变量时如何处理? 我是这样子做的 : 首先将变量本地话--分布式就放到大容器中,我这里仅仅使用了一个map来存 词和次数的关系映射 变量本地化后就是多线程的解决了--锁的设置-我仅仅是在操作时加了一个锁来解决这个问题 这样做后总体上应该能解决变量的问题了 最后还有一个线程顺序问题要解决下 当 最后一个提交索引时 获取的索引不一定是正确的索引

Solr入门 Linux中 配置tomcat7 jdk 1.7

一.环境准备: 系统环境:CentOS 6.5 Tomcat 7.0.26 jdk-7u17-linux-x64.rpm solr-4.10.1.tgz 首先将软件包上传到/tmp目录下 1.  jdk安装 ]# rpm -ivh jdk-7u17-linux-x64.rpm Preparing...               ########################################### [100%] 1:jdk                   #########

solr入门之搭建具有安全控制和权限管理功能的SolrCloud集群

结合上次搭建项目和配置安全控制的经验,工程的搭建过程应该如下: 1.搭建zookeeper集群 2.配置solr的jetty启动配置 3.在solr启动配置中增加zk的acl配置信息 4.使用solr配置,启动solrcloud集群将 集群交给zookeeper管理 5.上传相关的配置文件,创建集合 6.上传安全配置文件 7.登录admin界面,查看集群状态及能否访问到zookeeper上的文件 8.添加数据到solrcloud中 9.配置客户端,使用solrj来操作solrcloud(摸索阶段

solr入门之參考淘宝搜索提示功能优化拼音加汉字搜索功能

首先看一下从淘宝输入搜索keyword获取到的一些数据信息: 第一张:使用拼音的全程来查询 能够看到提示的是匹配的转换的拼音的方式,看最后一个提示项 这里另一个在指定分类文件夹下搜索的功能,难道后台还存储的类目的信息? 另一个标签的信息要存储 第二使用首字母来匹配 这里看不出来 淘宝的东西太多了,首字母直接有了相应的全程 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA

Solr入门指南

本文转自http://chuanliang2007.spaces.live.com/blog/cns!E5B7AB2851A4C9D2!499.entry?wa=wsignin1.0 因为搜索引擎功能在门户社区中对提高用户体验有着重在门户社区中涉及大量须要搜索引擎的功能需求.眼下在实现搜索引擎的方案上有集中方案可供选择: 1. 基于Lucene自己进行封装实现站内搜索.工作量及扩展性都较大,不採用. 2. 调用Google.Baidu的API实现站内搜索.同第三方搜索引擎绑定太死.无法满足后期业

solr入门教程-较详细

Solr调研总结 开发类型 全文检索相关开发 Solr版本 4.2 文件内容 本文介绍solr的功能使用及相关注意事项;主要包括以下内容:环境搭建及调试;两个核心配置文件介绍;维护索引;查询索引,和在查询中可以应用的高亮显示.拼写检查.搜索建议.分组统计.拼音检索等功能的使用方法. 版本 作者/修改人 日期 V1.0 gzk 2013-06-04       1. Solr 是什么? Solr它是一种开放源码的.基于 Lucene Java 的搜索服务器,易于加入到 Web 应用程序中.Solr

apache Solr 入门见解

最近项目中使用到了solr,记录一下solr的一些东西 下载solr,地址 http://mirror.bit.edu.cn/apache/lucene/solr/5.3.0/ 在linux目录下创建solr_home 和solr_tomcat 文件夹 其中,solr_home目录下的文件如下: 如果要配置多核的话,需配置core0和core1文件夹里面的文件,单核只 需 配置 collection1 bin目录里面无内容,可以忽略 因为项目用到多核,所以配置core0 和core1,由于配置c