全文搜索服务器solr之客户端 - solrj二次开发

华为OD机试 - 幸运数字(Java 2024 E卷 100分) 华为OD机试 2024E卷题库疯狂收录中,刷题。 阅读详情

Solrj已经是很强大的solr客户端了。它本身就包装了httpCliet,以完全对象的方式对solr进行交互。很小很好很强大。
    不过在实际使用中,设置SolrQuery 的过程中,为了设置多个搜索条件和排序规则等等参数,我们往往会陷入并接字符串的地步,实在是很丑陋,不符合面向对象的思想。扩展性几乎为0,。基于这点,开发了一个小东西,我们只需要设置搜索对象,将对象扔给后台就可以了。
    比如,我们搭建的solr服务支持某10个字段的搜索,我们要搜索其中的一些,那么我们只需要传入要搜索的对象POJO,将要搜索的字段内容,set到POJO对象对应额字段即可。

    比如如下一个类:

package org.uppower.tnt.biz.core.manager.blog.dataobject;

/**
 * @author yingmu
 * @version 2010-7-20 下午01:00:55
 */
public class SolrPropertyDO {
	private String auction_id;
	private String opt_tag;
	private String exp_tag;
	private String title;
	private String desc;
	private String brand;
	private String category;
	private String price;
	private String add_prov;
	private String add_city;
	private String quality;
	private String flag;
	private String sales;
	private String sellerrate;
	private String selleruid;
	private String ipv15;

	public String getAuction_id() {
		return auction_id;
	}

	public void setAuction_id(String auctionId) {
		auction_id = auctionId;
	}

    ……

	public String getExp_tag() {
		return exp_tag;
	}

	public void setExp_tag(String expTag) {
		exp_tag = expTag;
	}
}

那么我们在定义搜索对象时候,就按照如下设置:
SolrPropertyDO propertyDO = new SolrPropertyDO();
		propertyDO.setAdd_city("(杭州AND成都)OR北京");
		propertyDO.setTitle("丝绸OR剪刀");
         ……

设置排序条件,也是类似的做法:

SolrPropertyDO compositorDO = new SolrPropertyDO();
		compositorDO.setPrice ("desc");
		compositorDO.setQuality ("asc");
         ……

 将定义好的两个对象扔给后面的接口就可以了。

     接口函数querySolrResult传入四个参数,其中包含搜索字段对象,排序条件对象。为了提供类似limit的操作,用于分页查询,提供了startIndex和pageSize。
     函数querySolrResultCount是单纯为了获得搜索条数,配合分页使用。
    以下是定义的接口:

package org.uppower.tnt.biz.core.manager.blog;

import java.util.List;

import org.uppower.tnt.biz.core.manager.isearch.dataobject.SolrPropertyDO;

/**
 * @author yingmu
 * @version 2010-7-20 下午03:51:15
 */
public interface SolrjOperator {

	/**
	 * 获得搜索结果
	 * 
	 * @param propertyDO
	 * @param compositorDO
	 * @param startIndex
	 * @param pageSize
	 * @return
	 * @throws Exception
	 */
	public List<Object> querySolrResult(Object propertyDO,
			Object compositorDO, Long startIndex, Long pageSize)
			throws Exception;

	/**
	 * 获得搜索结果条数
	 * 
	 * @param propertyDO
	 * @param compositorDO
	 * @return
	 * @throws Exception
	 */
	public Long querySolrResultCount(SolrPropertyDO propertyDO,
			Object compositorDO) throws Exception;

}

 实现逻辑为,首先将传入的两个实体对象,解析为<K,V>结构的Map当中,将解析完成的Map放入solrj实际的搜索对象当中。返回的对象为solrj的API提供的SolrDocument,其中结果数量为直接返回SolrDocumentList对象的getNumFound()
    具体实现类:

package org.uppower.tnt.biz.core.manager.blog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.solr.common.SolrDocumentList;

import org.uppower.tnt.biz.core.manager.isearch.common.SolrjCommonUtil;
import org.uppower.tnt.biz.core.manager.isearch.dataobject.SolrPropertyDO;
import org.uppower.tnt.biz.core.manager.isearch.solrj.SolrjQuery;

/**
 * @author yingmu
 * @version 2010-7-20 下午03:51:15
 */
public class DefaultSolrOperator implements SolrjOperator {
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	private SolrjQuery solrjQuery;

	public void setSolrjQuery(SolrjQuery solrjQuery) {
		this.solrjQuery = solrjQuery;
	}

	@Override
	public List<Object> querySolrResult(Object propertyDO,
			Object compositorDO, Long startIndex, Long pageSize)
			throws Exception {
		Map<String, String> propertyMap = new TreeMap<String, String>();
		//排序有顺序,使用TreeMap
		Map<String, String> compositorMap = new TreeMap<String, String>();
		try {
			propertyMap = SolrjCommonUtil.getSearchProperty(propertyDO);
			compositorMap = SolrjCommonUtil.getSearchProperty(compositorDO);
		} catch (Exception e) {
			logger.error("SolrjCommonUtil.getSearchProperty() is error !"+ e);
		}
		SolrDocumentList solrDocumentList = solrjQuery.query(propertyMap, compositorMap,
				startIndex, pageSize);
		List<Object> resultList = new ArrayList<Object>();
		for (int i = 0; i < solrDocumentList.size(); i++) {
			resultList.add(solrDocumentList.get(i));
		}
		return resultList;
	}

	@Override
	public Long querySolrResultCount(SolrPropertyDO propertyDO,
			Object compositorDO) throws Exception {
		Map<String, String> propertyMap = new TreeMap<String, String>();
		Map<String, String> compositorMap = new TreeMap<String, String>();
		try {
			propertyMap = SolrjCommonUtil.getSearchProperty(propertyDO);
			compositorMap = SolrjCommonUtil.getSearchProperty(compositorDO);
		} catch (Exception e) {
			logger.error("SolrjCommonUtil.getSearchProperty() is error !" + e);
		}
		SolrDocumentList solrDocument = solrjQuery.query(propertyMap, compositorMap,
				null, null);
		return solrDocument.getNumFound();
	}

}

其中,对象的解析式利用反射原理,将实体对象中不为空的值,以映射的方式,转化为一个Map,其中排序对象在转化的过程中,使用TreeMap,保证其顺序性。
    解析公共类实现如下:

package org.uppower.tnt.biz.core.manager.blog.common;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yingmu
 * @version 2010-7-20 下午01:07:15
 */
public class SolrjCommonUtil {

	public static Map<String, String> getSearchProperty(Object model)
			throws NoSuchMethodException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException {
		Map<String, String> resultMap = new TreeMap<String, String>();
		// 获取实体类的所有属性,返回Field数组
		Field[] field = model.getClass().getDeclaredFields();
		for (int i = 0; i < field.length; i++) { // 遍历所有属性
			String name = field[i].getName(); // 获取属性的名字
			// 获取属性的类型
			String type = field[i].getGenericType().toString();
			if (type.equals("class java.lang.String")) { // 如果type是类类型,则前面包含"class ",后面跟类名
				Method m = model.getClass().getMethod(
						"get" + UpperCaseField(name));
				String value = (String) m.invoke(model); // 调用getter方法获取属性值
				if (value != null) {
					resultMap.put(name, value);
				}
			}
		}
		return resultMap;
	}

	// 转化字段首字母为大写
	private static String UpperCaseField(String fieldName) {
		fieldName = fieldName.replaceFirst(fieldName.substring(0, 1), fieldName
				.substring(0, 1).toUpperCase());
		return fieldName;
	}

}

搜索直接调用solr客户端solrj,基本逻辑为循环两个解析之后的TreeMap,设置到SolrQuery当中,最后直接调用solrj的API,获得搜索结果。最终将搜索结构以List<Object>的形式返回。
    具体实现:

package org.uppower.tnt.biz.core.manager.blog.solrj;

import java.net.MalformedURLException;
import java.util.Map;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList;

/**
 * @author yingmu
 * @version 2010-7-20 下午02:57:04
 */
public class SolrjQuery {
	private String url;
	private Integer soTimeOut;
	private Integer connectionTimeOut;
	private Integer maxConnectionsPerHost;
	private Integer maxTotalConnections;
	private Integer maxRetries;
	private CommonsHttpSolrServer solrServer = null;
	private final static String ASC = "asc";

	public void init() throws MalformedURLException {
		solrServer = new CommonsHttpSolrServer(url);
		solrServer.setSoTimeout(soTimeOut);
		solrServer.setConnectionTimeout(connectionTimeOut);
		solrServer.setDefaultMaxConnectionsPerHost(maxConnectionsPerHost);
		solrServer.setMaxTotalConnections(maxTotalConnections);
		solrServer.setFollowRedirects(false);
		solrServer.setAllowCompression(true);
		solrServer.setMaxRetries(maxRetries);
	}

	public SolrDocumentList query(Map<String, String> propertyMap,
			Map<String, String> compositorMap, Long startIndex, Long pageSize)
			throws Exception {
		SolrQuery query = new SolrQuery();
		// 设置搜索字段
		if (null == propertyMap) {
			throw new Exception("搜索字段不可为空!");
		} else {
			for (Object o : propertyMap.keySet()) {
				StringBuffer sb = new StringBuffer();
				sb.append(o.toString()).append(":");
				sb.append(propertyMap.get(o));
				String queryString = addBlank2Expression(sb.toString());
				query.setQuery(queryString);
			}
		}
		// 设置排序条件
		if (null != compositorMap) {
			for (Object co : compositorMap.keySet()) {
				if (ASC == compositorMap.get(co)
						|| ASC.equals(compositorMap.get(co))) {
					query.addSortField(co.toString(), SolrQuery.ORDER.asc);
				} else {
					query.addSortField(co.toString(), SolrQuery.ORDER.desc);
				}
			}
		}
		
		if (null != startIndex) {
			query.setStart(Integer.parseInt(String.valueOf(startIndex)));
		}
		if (null != pageSize && 0L != pageSize.longValue()) {
			query.setRows(Integer.parseInt(String.valueOf(pageSize)));
		}
		try {
			QueryResponse qrsp = solrServer.query(query);
			SolrDocumentList docs = qrsp.getResults();
			return docs;
		} catch (Exception e) {
			throw new Exception(e);
		}
	}

	private String addBlank2Expression(String oldExpression) {
		String lastExpression;
		lastExpression = oldExpression.replace("AND", " AND ").replace("NOT",
				" NOT ").replace("OR", " OR ");
		return lastExpression;
	}

	public Integer getMaxRetries() {
		return maxRetries;
	}

	……
      
        public void setMaxTotalConnections(Integer maxTotalConnections) {
		this.maxTotalConnections = maxTotalConnections;
	}
}

整个实现是在Spring的基础上完成的,其中SolrjQuery的init()方法在Spring容器启动是初始化。Init()方法内的属性,也是直接注入的。上层与下层之间也完全用注入的方式解决。具体配置就不贴不出来了,大家都会。

整个代码很简陋,但是几乎支持了你想要搜索的条件设置,而且不会暴露任何与solr相关的内容给上层调用,使整个搜索几乎以sql语言的思想在设置条件。


http://www.iteye.com/topic/315330


package org.nstcrm.person.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList;

public class SolrHttpServer {
	//private Logger logger = LoggerFactory.getLogger(this.getClass());
	private final static String URL = "http://localhost:8080/solr";
	private final static Integer SOCKE_TTIMEOUT = 1000; // socket read timeout
	private final static Integer CONN_TIMEOUT = 100;
	private final static Integer MAXCONN_DEFAULT = 100;
	private final static Integer MAXCONN_TOTAL = 100;
	private final static Integer MAXRETRIES = 1;
	private static CommonsHttpSolrServer server = null;
	private final static String ASC = "asc";
	
	public void init() throws MalformedURLException {
			server = new CommonsHttpSolrServer( URL );
			//server.setParser(new XMLResponseParser());
			server.setSoTimeout(SOCKE_TTIMEOUT);
			server.setConnectionTimeout(CONN_TIMEOUT);
			server.setDefaultMaxConnectionsPerHost(MAXCONN_DEFAULT);
			server.setMaxTotalConnections(MAXCONN_TOTAL);
			server.setFollowRedirects(false);
			server.setAllowCompression(true);
			server.setMaxRetries(MAXRETRIES);
	}
	
	public static SolrDocumentList query(Map<String, String> property, Map<String, String> compositor, Integer pageSize) throws Exception {
		SolrQuery query = new SolrQuery();
		// 设置搜索字段
		if(null == property) {
			throw new Exception("搜索字段不可为空!");
		} else {
			for(Object obj : property.keySet()) {
				StringBuffer sb = new StringBuffer();
				sb.append(obj.toString()).append(":");
				sb.append(property.get(obj));
				String sql = (sb.toString()).replace("AND", " AND ").replace("OR", " OR ").replace("NOT", " NOT ");
				query.setQuery(sql);
			}
		}
		// 设置结果排序
		if(null != compositor) {
			for(Object obj : compositor.keySet()) {
				if(ASC == compositor.get(obj) || ASC.equals(compositor.get(obj))) {
					query.addSortField(obj.toString(), SolrQuery.ORDER.asc);
				} else {
					query.addSortField(obj.toString(), SolrQuery.ORDER.desc);
				}
			}
		}
		if(null != pageSize && 0 < pageSize) {
			query.setRows(pageSize);
		}
		QueryResponse qr = server.query(query);
		SolrDocumentList docList = qr.getResults();
		return docList;
	}
	
	public static Map<String, String> getQueryProperty(Object obj) throws Exception {
		Map<String, String> result = new TreeMap<String, String>();
		// 获取实体类的所有属性,返回Fields数组
		Field[] fields = obj.getClass().getDeclaredFields();
		for(Field f : fields) {
			String name = f.getName();// 获取属性的名字
			String type = f.getGenericType().toString();
			if("class java.lang.String".equals(type)) {// 如果type是类类型,则前面包含"class ",后面跟类名
				Method me = obj.getClass().getMethod("get" + UpperCaseField(name));
				String tem = (String) me.invoke(obj);
				if(null != tem) {
					result.put(name, tem);
				}
			}
		}
		return result;
	}
	
	public static List<Object> querySolrResult(Object propertyObj, Object compositorObj, Integer pageSize) throws Exception {
		Map<String, String> propertyMap = new TreeMap<String, String>();
		Map<String, String> compositorMap = new TreeMap<String, String>();
		propertyMap = getQueryProperty(propertyObj);
		compositorMap = getQueryProperty(compositorObj);
		SolrDocumentList docList = query(propertyMap, compositorMap, pageSize);
		List<Object> list = new ArrayList<Object>();
		for(Object obj : docList) {
			list.add(obj);
		}
		return list;
	}
	
	private static String UpperCaseField(String name) {
		return name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
	}

	public CommonsHttpSolrServer getServer() {
		return server;
	}

	public void setServer(CommonsHttpSolrServer server) {
		this.server = server;
	}

}


Solr 1.4.1配置和SolrJ的用法
一、	Solr基本安装和配置
1,从官网镜像服务器下载最新版本apache-solr-1.4.1。下载地址: 
http://apache.etoak.com//lucene/solr/,并解压缩
2,在D盘建立一个SolrHome文件夹来存放solr的配置文件等,例如:在D盘WORK目录下穿件一个SolrHome文件夹: D:\WORK\SolrHome,
3,在刚解压的apache-solr-1.4.1,找到apache-solr-1.4.1\example下找到solr文件夹,复制到SolrHome下.
4,将apache-solr-1.4.1\dist\apache-solr-1.4.1.war中的apache-solr-1.4.1.war复制到tomcat中的\webapps下并重命名为solr,启动tomcat,解压war包后,停止tomcat.
5,在解压后的solr中找到web.xml,打开:将<env-entry-value>的值设为SolrHome的目录地址
	<env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>D:\WORK\SolrHome\solr</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>
6,在D:\WORK\SolrHome\solr\conf找到solrconfig.xml文件,打开,修改
	<dataDir>${solr.data.dir:./solr/data}</dataDir>
 其中solr.data.dir存放的是索引目录.
7,添加中文支持,修改tomcat的配置文件server.xml,如下:
			<Connector port="80" protocol="HTTP/1.1" 
               maxThreads="150" connectionTimeout="20000" 
               redirectPort="8443" URIEncoding="UTF-8"/>
8,启动tomcat,IE中输入:http://localhost:80/solr 即可浏览solr服务器.
二、Solr服务器复制的配置
1,首先测试在本机上开启三个tomcat的服务器:一个端口是80,另一个是9888
2,按照标题一的配置对第二和第三个tomcat服务器进行类似的配置,注意SolrHome的目录不要相同即可,其他的配置不变. 例如:以本机为例


tomcat命名	     URL	SolrHome目录URI	      web.xml配置
tomcat0 (master)	http://localhost:80/solr	D:\WORK\SolrHome\solr	<env-entry-value>D:\WORK\SolrHome\solr</env-entry-value>
tomcat1 (slave)	http://localhost:9888/solr	E:\WORK\SolrHome\solr	<env-entry-value>E:\WORK\SolrHome\solr</env-entry-value>
tomcat2
(salve)	http://localhost:9008/solr	F:\WORK\SolrHome\solr	<env-entry-value>F:\WORK\SolrHome\solr</env-entry-value>




3,以上两步配置好之后,在主服务器tomcat0(master)的SolrHome中找到solrconfig.xml文件,加入如下配置.
	<requestHandler name="/replication" class="solr.ReplicationHandler" >
    <lst name="master">
      <str name="replicateAfter">commit</str>
      <str name="replicateAfter">startup</str>
      <str name="confFiles">schema.xml,stopwords.txt</str>
    </lst>
 </requestHandler>
在从服务器tomcat1(slave)和tomcat1(slave)的SolrHome中找到solrconfig.xml文件加入如下配置:
	<requestHandler name="/replication" class="solr.ReplicationHandler" >  
	  	<lst name="slave">  
	      <str name="masterUrl">http://localhost/solr/replication</str>  
	      <str name="pollInterval">00:00:60</str>  
	    </lst>  
	</requestHandler>
4,在tomcat0上创建索引,使用客户端solrj创建索引,jar包在apache-solr-1.4.1压缩包中.代码如下:
  public class SlorTest3 {
	private static CommonsHttpSolrServer  server = null;
//	private static SolrServer server = null;
	public SlorTest3(){
		try {
			server = new CommonsHttpSolrServer("http://localhost/solr");
			server.setConnectionTimeout(100);
			server.setDefaultMaxConnectionsPerHost(100);
			server.setMaxTotalConnections(100);
		} catch (IOException e) {
			e.printStackTrace();
		}
			
	}
	@Test
	public void testIndexCreate(){
		List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
		for(int i=300;i<500;i++){
			SolrInputDocument doc = new SolrInputDocument();
			doc.addField("zjid", i);  //需要在sechma.xml中配置字段
			doc.addField("title", "云状空化多个气泡的生长和溃灭");
			doc.addField("ssid", "ss"+i);
			doc.addField("dxid", "dx"+i);
			docs.add(doc);
		}
			try {
				server.add(docs);
				server.commit();
				System.out.println("----索引创建完毕!!!----");
			} catch (SolrServerException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
	}
}
5,分别启动三台tomcat服务器.打开IE浏览器分别输入:其中localhost=192.168.169.121
http://localhost:9888/solr 点击 即可从主solr服务器上复制索引
   

三、Solr服务器分发(shard)配置
1,	开启四台tomcat服务器,其中三台在本机上,一台在远端.清单如下:
 注意:四台服务器的配置要相同.其中的schema.xml字段配置一定要一致.

Name	     URL	SolrHome目录URI	
tomcatQuery	http://localhost:80/solr	D:\WORK\SolrHome\solr	
tomcat0 (shard)	http://localhost:9888/solr	E:\WORK\SolrHome\solr	
tomcat1 (shard)	http://localhost:9008/solr	F:\WORK\SolrHome\solr	
tomcat2 (shard)	http://192.168.169.48:9888/solr	D:\WORK\SolrHome\solr	



2,	配置较简单,只需要在tomcatQuery上的SoleHome的solrconfig.xml文件中修改
其他的solr服务器不需要配置。
  <requestHandler name="standard" class="solr.SearchHandler" default="true">
    <!-- default values for query parameters -->
     <lst name="defaults">
       <str name="echoParams">explicit</str>
       <str name="shards">localhost:9088/solr,localhost:9888/solr,192.168.169.48:9888/solr</str>
       <!--
       <int name="rows">10</int>
       <str name="fl">*</str>
       <str name="version">2.1</str>
        -->
     </lst>
  </requestHandler>
3,	使用slorj的清除原有的索引.或者手动删除。
4,	编写代码,将lucene建立的索引(1G左右,874400条记录),按照比例通过solrj分发到三台solr(shard)服务器上,代码如下:
public class IndexCreate{
	private static CommonsHttpSolrServer server;
	public  CommonsHttpSolrServer getServer(String hostUrl){
		CommonsHttpSolrServer server = null;
		try {
			server = new CommonsHttpSolrServer(hostUrl);
			server.setConnectionTimeout(100);
			server.setDefaultMaxConnectionsPerHost(100);
			server.setMaxTotalConnections(100);
		} catch (IOException e) {
			System.out.println("请检查tomcat服务器或端口是否开启!");
		}
		return server;
	}
	@SuppressWarnings("deprecation")
	public void readerHostCreate(String[] hosts) throws CorruptIndexException, IOException{
		IndexReader reader = IndexReader.open("c:\\index");
		System.out.println("总记录数: "+reader.numDocs());
		int hostNum = hosts.length;
		int lengh = reader.numDocs()/hostNum; //根据主机数平分索引长度
		int j = reader.numDocs()%hostNum;     //取余
		for(int i = 0;i<hosts.length;i++){
			long startTime = new Date().getTime();
			String url = hosts[i].substring(hosts[i].indexOf("//")+2,hosts[i].lastIndexOf("/"));
			System.out.println("第"+(i+1)+"次,在主机:"+url+" 上创建索引,创建时间"+new Date());
			if(i==(hosts.length-1)){
				hostlist(reader,lengh*i,lengh*(i+1)+j,hosts[i]);
			
			}else{
				hostlist(reader,lengh*i,lengh*(i+1),hosts[i]);
			}
			System.out.println("结束时间"+new Date());
			long endTime = new Date().getTime();
			long ms = (endTime-startTime)%60000-(((endTime-startTime)%60000)/1000)*1000;
			System.out.println("本次索引创建完毕,一共用了"+(endTime-startTime)/60000+"分" +
					""+((endTime-startTime)%60000)/1000+"秒"+ms+"毫秒");
			System.out.println("****************************");
		}
		reader.close();
	}
	@SuppressWarnings("static-access")
	public void hostlist(IndexReader reader,int startLengh,int endLengh,String hostUrl) throws CorruptIndexException, IOException{
		List<BookIndex> beans = new LinkedList<BookIndex>();
		int count = 0;
		this.server = getServer(hostUrl);
		for(int i=startLengh;i<endLengh;i++){
			Document doc = reader.document(i);
			BookIndex book = new BookIndex();
			book.setZjid(doc.getField("zjid").stringValue());
			book.setTitle(doc.getField("title").stringValue());
			book.setSsid(doc.getField("ssid").stringValue());
			book.setDxid(doc.getField("dxid").stringValue());
			book.setBookname(doc.getField("bookname").stringValue());
			book.setAuthor(doc.getField("author").stringValue());
			book.setPublisher(doc.getField("publisher").stringValue());
			book.setPubdate(doc.getField("pubdate").stringValue());
			book.setYear(doc.getField("year").stringValue());
			book.setFenlei(doc.getField("fenlei").stringValue());
			book.setscore1(doc.getField("score").stringValue());
			book.setIsbn(doc.getField("isbn").stringValue());
			book.setFenleiurl(doc.getField("fenleiurl").stringValue());
			book.setMulu(doc.getField("mulu").stringValue());
			book.setIsp(doc.getField("isp").stringValue());
			book.setIep(doc.getField("iep").stringValue());
			beans.add(book);
			if(beans.size()%3000==0){
				createIndex(beans,hostUrl,server);
				beans.clear();
				System.out.println("---索引次数:"+(count+1)+"---");
				count++;
			}
		}
		System.out.println("beansSize 的大小 "+beans.size());
		if(beans.size()>0){
			createIndex(beans,hostUrl,server);
			beans.clear();
		}
		
	}
	public void createIndex(List<BookIndex> beans,String hostUrl,CommonsHttpSolrServer server){
		try {
				server.addBeans(beans);
				server.commit();
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) throws CorruptIndexException, IOException{
		IndexCreate as = new IndexCreate();
		String[] hosts = new String[] {"http://192.168.169.121:9888/solr","http://192.168.169.121:9088/solr","http://192.168.169.48:9888/solr"};
		long startTime = new Date().getTime();
		as.readerHostCreate(hosts);
		long endTime = new Date().getTime();
		System.out.println("-------------------");
		long ms = (endTime-startTime)%60000-(((endTime-startTime)%60000)/1000)*1000;
		System.out.println("全部索引创建完毕,一共用了"+(endTime-startTime)/60000+"分" +
				""+((endTime-startTime)%60000)/1000+"秒"+ms+"毫秒");
	}

}
JavaBean类BookIndex.java代码如下:
说明变量名与sechma.xml中的配置要相同.注意:不能使用score这个变量或者字段,与slor配置冲突,报exception。
import org.apache.solr.client.solrj.beans.Field;

public class BookIndex {
	@Field  
	private String zjid ;
	@Field  
	private String title;
	@Field  
	private String ssid;
	@Field  
	private String dxid;
	@Field 
	private String bookname;
	@Field 
	private String author;
	@Field 
	private String publisher;
	@Field 
	private String pubdate;
	@Field 
	private String year;
	@Field 
	private String fenlei;
	@Field 
	private String score1;
	@Field 
	private String isbn;
	@Field 
	private String fenleiurl;
	@Field 
	private String mulu;
	@Field 
	private String isp;
	@Field 
	private String iep;
	public getters();//get方法
	public setters();//set方法
}


5,	同时开启四台服务器,运行上面代码:
6,	打开IE查询
打开:http://localhost/solr
打开:http://localhost:9888/solr
打开http://localhost:9008/solr
打开http://192.168.168.48:9888/solr

四、Solr的Multicore(分片)配置
第一步,将apache-solr-1.4.1\example下的multicore复制到先前配置的solr/home下。
	其中multicore下的solr.xml配置如下:
<solr persistent="false">
   <cores adminPath="/admin/cores">
	<core name="core0" instanceDir="core0">  
	  <property name="dataDir" value="/data/core0" />  
    </core>
    <core name="core1" instanceDir="core1">
	  <property name="dataDir" value="/data/core1" />  
    </core>
	<core name="core2" instanceDir="core2">
	  <property name="dataDir" value="/data/core2" />  
    </core>
  </cores>
</solr>
第二步,修改Tomcat 6.0\webapps\solr\WEB-INF下的web.xml文件如下
<env-entry-value>D:\WORK\SolrHome\multicore</env-entry-value>
第三步,开启服务器,打开IEhttp://localhost/solr
 
五、SolrJ的用法
1,SolrJ的用法
  solrJ是与solr服务器交互的客户端工具.使用solrJ不必考虑solr服务器的输出格式,以及对文档的解析。solrJ会根据用户发送的请求将数据结果集(collection)返回给用户.
2,使用SolrJ建立索引
  事例代码:
//得到连接solr服务器的CommonsHttpSolrServer对象.通过这个对象处理用户提交的请求:
 CommonsHttpSolrServer server = new CommonsHttpSolrServer("http://localhost:9888/solr");
public void testIndexCreate(){
		List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
// SolrInputDocumentle类似与Document类,用于创建索引文档,和向文档中添加字段
		for(int i=300;i<500;i++){
			SolrInputDocument doc = new SolrInputDocument();
			doc.addField("zjid", i+"_id");  
			doc.addField("title", i+"_title");
			doc.addField("ssid", "ss_"+i);
			doc.addField("dxid", "dx_"+i);
			docs.add(doc);
		}
			try {
				server.add(docs);
				server.commit();//以更新(update)的方式提交
				System.out.println("----索引创建完毕!!!----");
			} catch (SolrServerException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
	}
以javaBean的方式创建索引:
public class BookIndex {
	@Field
	private String zjid;
	@Field
	private String zhangjie;
	@Field
	private String ssid;
	@Field
	private String qwpos;
	@Field
	private String publishDate;
	@Field
	private String mulu;
	@Field
	private String fenleiurl;
	@Field
	private String fenlei;
	@Field
	private String dxid;
	@Field
	private String author;
	@Field
	private String address;
	@Field
	private String bookname;
…………………
}
public void testBean(){
		List<BookIndex> beans = new ArrayList<BookIndex>();
		for(int i=0;i<10;i++){
			BookIndex book = new BookIndex();
			book.setZjid(i+"id");
			book.setTitle(i+"title");
			//set方法
			beans.add(book);
		}
		try {
			server.addBeans(beans);
			server.commit();
			System.out.println("----索引创建完毕!!!----");
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
3,	SolrJ常见的查询 
  a,  查询索引中的全部字段的内容:  SolrQuery query = new SolrQuery("*:*");
   事例代码:
   public void testQuery1(){
		SolrQuery query = new SolrQuery("*:*");
		query.setStart(20);//设置起始位置
		query.setRows(10); //查询组数
		QueryResponse response = null; 
		try {
			response = server.query(query);//响应向服务器提交的查询请求
			System.out.println(response);
		} catch (SolrServerException e) {
			e.printStackTrace();
		}
		
		List<SolrDocument> docs = response.getResults();//得到结果集
		for(SolrDocument doc:docs){//遍历结果集
			for(Iterator iter = doc.iterator();iter.hasNext();){
Map.Entry<String, Object> entry = (Entry<String, Object>)iter.next();
				System.out.print("Key :"+entry.getKey()+"  ");
				System.out.println("Value :"+entry.getValue());
			}
			System.out.println("------------");
		}	
}
b, 查询某一字段的内容
	String queryString  = “zjid:5_id”;//写法为字段名:查询的内容
    SolrQuery query = new SolrQuery(queryString);
c, 查询copyField的内容
   copyField是查询的默认字段,当不指明查询字段的field的时。查询的请求会在copyField匹配: 详细参见schema..xml的配置.
	String queryString  = “XXX”
   SolrQuery query = new SolrQuery(queryString);
4,	索引删除
事例代码 :
 public void testClear() {
		server.setRequestWriter(new BinaryRequestWriter());//提高性能采用流输出方式
		try {
			server.deleteByQuery("*:*");
			server.commit();
			System.out.println("----清除索引---");
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
5,	高亮的使用Highlight
public List<Book> getQueryString(String queryString,int start,int pageSize) {
		SolrQuery query = new SolrQuery(queryString);
		query.setHighlight(true); //开启高亮组件
		query.addHighlightField("mulu");//高亮字段
		query.setHighlightSimplePre("<font color=\"red\">");//标记
		query.setHighlightSimplePost("</font>");
		query.set("hl.usePhraseHighlighter", true);
		query.set("hl.highlightMultiTerm", true);
		query.set("hl.snippets", 3);//三个片段,默认是1
		query.set("hl.fragsize", 50);//每个片段50个字,默认是100
		//
		query.setStart(start); //起始位置 …分页
		query.setRows(pageSize);//文档数
		
		try {
			response = server.query(query);
		} catch (SolrServerException e) {
			e.printStackTrace();
		}
		List<BookIndex> bookLists = response.getBeans(BookIndex.class);
		Map<String,Map<String,List<String>>> h1 = response.getHighlighting();
		
		List<Book> books = new ArrayList<Book>();
		for(BookIndex bookIndex : bookLists){
			Map<String,List<String>>  map = h1.get(bookIndex.getZjid());
//以文档的唯一id作为Map<String,Map<String,List<String>>>的key值.
			Book book = new Book();
			//copy字段
			book.setBookname(bookIndex.getBookname());
			book.setZjid(bookIndex.getZjid());
			if(map.get("mulu")!=null){
				List<String> strMulu = map.get("mulu");
				StringBuffer buf  = new StringBuffer();
				for(int i =0;i<strMulu.size();i++){
					buf.append(strMulu.get(i));
					buf.append("...");
					if(i>3){
						break;
					}
				}
				book.setSummary(buf.toString());
			}else{
				if(bookIndex.getMulu().length()>100){
					book.setSummary(bookIndex.getMulu().substring(0,100)+"...");
				}else{
					book.setSummary(bookIndex.getMulu()+"...");
				}
				
			}
				books.add(book);
		}
		return books;
	
	}
6, 分组Fact
//需要注意的是参与分组的字段是不需要分词的,比如:产品的类别.kind
public void testFact(){
		String queryString = "kind:儿童图书";
		SolrQuery query = new SolrQuery().setQuery(queryString);
		query.setFacet(true); //开启分组
		query.addFacetField("bookname");//分组字段
query.addFacetField("title");
		query.setFacetMinCount(1);
query.addSortField( "zjid", SolrQuery.ORDER.asc );//排序字段

		query.setRows(10);
		QueryResponse response = null;
		try {
			response = server.query(query);
			System.out.println(response);
		} catch (SolrServerException e) {
			e.printStackTrace();
		}
		List<FacetField> facets = response.getFacetFields();
		for (FacetField facet : facets) {
		  System.out.println("Facet:" + facet);
		}
		
	} 

六、一个简单的web引用:
 首先说明的是索引来源,是根据已有的lucene索引上开发的,又因为lucene的索引直接用solrJ应用效果不好,会出现很多问题,找不到类似的解决办法,比如全字段查询,和高亮分组等,和多级索引目录…。但用solrJ创建的索引不存在类似的问题.
 大致的思路是,读取已有的lucene索引 ,再用solrJ创建索引并分发到多台机器上,最后再做开发.
 第一步:读取lucene的多级索引目录,用solrJ创建和分发索引;
需注意的是:要加大虚拟机的内存,因为采用的map做为缓存,理论上虚拟机的内存大,map的存储的索引文档数也就多.主要是针对内存溢出.
  代码 :
package org.readerIndex;
import org.apache.solr.client.solrj.beans.Field;
public class BookIndex2 {
	@Field
	private String zjid;
	@Field
	private String zhangjie;
	@Field
	private String ssid;
	@Field
	private String qwpos;
	@Field
	private String publishDate;
	@Field
	private String mulu;
	@Field
	private String fenleiurl;
	@Field
	private String fenlei;
	@Field
	private String dxid;
	@Field
	private String author;
	@Field
	private String address;
	@Field
	private String bookname;
	public String getZjid() {
		return zjid;
   …………………………………………
	}
package org.readerIndex;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;




public class ReaderIndex {
	public  CommonsHttpSolrServer getServer(String hostUrl){
		CommonsHttpSolrServer server = null;
		try {
			server = new CommonsHttpSolrServer(hostUrl);
			server.setConnectionTimeout(100);
			server.setDefaultMaxConnectionsPerHost(100);
			server.setMaxTotalConnections(100);
		} catch (IOException e) {
			System.out.println("请检查tomcat服务器或端口是否开启!");
		}
		return server;
	}
	public void indexDocuements(String path,String[] hostUrls) throws CorruptIndexException, LockObtainFailedException, IOException{
		File pareFile = new File(path);
		List<String> list = new ArrayList<String>();
		getFile(pareFile,list); //递归方法得到路径保存到list中
		System.out.println("***程序一共递归到"+list.size()+"个索引目录***");
		int arevageSize = list.size()/hostUrls.length;// 根据主机数平分目录
		int remainSize  = list.size()%hostUrls.length;//取余
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		for(int i=0;i<hostUrls.length;i++){
			Date startDate = new Date();
			String url = hostUrls[i].substring(hostUrls[i].indexOf("//")+2,hostUrls[i].lastIndexOf("/"));
			System.out.println("第"+(i+1)+"次,在主机:"+url+" 上创建索引,创建时间  "+sdf.format(startDate));
			if(i==(hostUrls.length-1)){
				list(list,arevageSize*i,arevageSize*(i+1)+remainSize,hostUrls[i]);
			}else{
				list(list,arevageSize*i,arevageSize*(i+1),hostUrls[i]);
			}
			Date endDate = new Date();
			System.out.println("本次索引结束时间为:"+sdf.format(endDate));
		}

	}
	public void list(List<String> list,int start,int end,String url){
		CommonsHttpSolrServer server = getServer(url);
		for(int j=start;j<end;j++){
			try {
				long startMs = System.currentTimeMillis();
				hostCreate(list.get(j),server);
				long endMs = System.currentTimeMillis();
				System.out.println("程序第"+(j+1)+"个目录处理完毕,目录路径:"+list.get(j)+", 耗时"+(endMs-startMs)+"ms");
			} catch (CorruptIndexException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	public void getFile(File fileDirectory,List<String> list){
		if(fileDirectory.isDirectory()){
			File[] files = fileDirectory.listFiles();
			for(File file :files){
			getFile(file,list);
			}
		}else if(fileDirectory.isFile()){
			String filePath = fileDirectory.getPath();
			String path = filePath.replace('\\', '/');
			if(path.endsWith(".cfs")){
				int lastIndex = path.lastIndexOf("/");
				String directory = path.substring(0,lastIndex);
				list.add(directory);
			}
		}
	}
	@SuppressWarnings("deprecation")
	public void hostCreate(String directory,CommonsHttpSolrServer server) throws CorruptIndexException, IOException{
		IndexReader reader = IndexReader.open(directory);
		List<BookIndex2> beans = new ArrayList<BookIndex2>();
		for(int i=0;i<reader.numDocs();i++){
			Document doc = reader.document(i);
			BookIndex2 book = new BookIndex2();
			book.setZjid(doc.getField("zjid").stringValue());
			book.setAddress(doc.getField("address").stringValue());
			book.setAuthor(doc.getField("author").stringValue());
			book.setbookname(doc.getField("bookname").stringValue());
			book.setDxid(doc.getField("dxid").stringValue());
			book.setFenlei(doc.getField("fenlei").stringValue());
			book.setFenleiurl(doc.getField("fenleiurl").stringValue());
			book.setMulu(doc.getField("mulu").stringValue());
			book.setPublishDate(doc.getField("publishDate").stringValue());
			book.setQwpos(doc.getField("qwpos").stringValue());
			book.setSsid(doc.getField("ssid").stringValue());
			book.setZhangjie(doc.getField("zhangjie").stringValue());
			beans.add(book);
			}
		createIndex(beans,server);
		beans.clear();
		reader.close();
	}
	public void createIndex(List<BookIndex2> beans,CommonsHttpSolrServer server){
		try {
				server.addBeans(beans);
				server.commit();
//				server.optimize();
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws CorruptIndexException, IOException{
		ReaderIndex reader = new ReaderIndex();
		String path = "D:\\91";
		String[] hosts = new String[] {"http://192.168.169.121:9888/solr","http://192.168.169.121:9088/solr","http://192.168.169.48:9888/solr"};
		
		long startTime = new Date().getTime();
		reader.indexDocuements(path,hosts);
		long endTime = new Date().getTime();
		System.out.println("-------------------");
		long ms = (endTime-startTime)%60000-(((endTime-startTime)%60000)/1000)*1000;
		System.out.println("全部文档索引完毕,一共用了"+(endTime-startTime)/60000+"分" +
				""+((endTime-startTime)%60000)/1000+"秒"+ms+"毫秒");
		
	}
		
	
}











第二步,进行简单的web应用.
 
 

共享单车数据抓取与分析:使用Python爬虫抓取共享单车使用数据与地图信息 通过本篇博客,我们展示了如何使用Python爬虫抓取共享单车的使用数据和地图信息,并通过简单的数据分析得出有价值的见解。在实际应用中,数据的收集与分析不仅能帮助城市管理者更好地规划单车站点,还能为用户提供更精准的单车使用体验。未来,我们可以将此分析与机器学习模型相结合,进一步预测单车的使用趋势,优化调度算法,实现更加智能的共享单车管理。 阅读详情

相关推荐

保姆级教程:用LoRA微调Chinese-Mistral-7B模型,并一键部署到Ollama(附完整代码)

本文提供了一份详细的LoRA微调Chinese-Mistral-7B模型的保姆级教程,涵盖环境配置、数据预处理、微调实战、模型量化及Ollama部署全流程。通过实战案例和完整代码,帮助开发者快速构建专属中文大模型,适用于医疗、法律等垂直领域。

weixin_30369041的博客 249

全文检索可视化动态管理(二)--solr二次开发和solrj扩展

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34261415的博客 247

Innovus快捷键大全:从入门到精通的效率提升指南

本文是Innovus快捷键从入门到精通的效率提升指南,旨在帮助芯片后端设计工程师通过掌握核心快捷键,将重复性鼠标操作转化为高效的肌肉记忆,从而显著提升版图设计、编辑和分析的工作流速度。文章系统讲解了视图导航、对象选择编辑、流程管理等关键快捷键组合,并提供了个性化配置与实战策略,助力工程师突破效率瓶颈,实现人机合一的流畅设计体验。

silver的专栏 797

solr快速上手:整合SolrJ实现客户端操作(九)

SolrJ是 Solr官方提供的 Java 客户端库,主要用于与 Solr 服务器进行交互。内部封装了一组API,可以方便地实现对solr服务端的各类操作。使用 SolrJ,可以通过编写 Java 代码来实现对 Solr 的索引操作,比如增删改查。同时,SolrJ 还支持多种查询方式,如简单查询、复杂查询、分页查询、聚合查询等。同时也包括了对solr的索引管理、权限控制等操作更多的客户端操作,还要大家自己去探索,但是直接使用SolrJ还是感觉有些复杂,能不能更加简易地实现客户端操作呢,那就要提到我们的。

55555的博客 2210

PTA 编程题(C语言)-- 然后是几点

PTA 编程题(C语言)-- 然后是几点

LCCprogrammer 5074

偷懒必备:3种方法快速移植MFC界面资源(含.rc文件打不开解决方案)

本文针对MFC桌面应用开发,详细介绍了三种快速移植界面资源的实战方法:直接编辑.rc文件、利用Visual Studio“添加现有项”进行可视化挂载,以及双实例拖拽应急方案。文章重点剖析了.rc文件无法打开的常见问题,提供了通过修复rc.exe等关键文件来根治此问题的解决方案,帮助开发者高效复用资源,规避ID冲突等陷阱。

weixin_28358083的博客 272

php solr 全文检索,全文检索可视化动态管理(二)--solr二次开发和solrj扩展

要完成solr的索引动态配置,需要solr提供动态新建、修改配置等的接口。solr虽提供core的添加删除,但不提供schema.xml修改新建接口,并且如果添加一个新core,也要将另一个core的conf配置文件复制一份到新的core文件夹下,然后管理页载入新的core。因此需要二次开发。查看solr的web.xml,可以发现请求链接都进入org.apache.solr.servlet.Sol...

weixin_33146151的博客 268

Matplotlib图片尺寸调整全攻略:从figsize到savefig的实战技巧

在数据可视化与科学计算中,图形尺寸控制是影响图表可读性与专业度的基础环节。其核心原理在于协调逻辑尺寸(英寸)与物理输出(像素)的映射关系,这直接决定了信息呈现的清晰度与布局合理性。从技术价值看,精准的尺寸控制能提升图表在不同媒介(如学术论文、报告、网页)中的适配性,避免显示不全、模糊失真等常见问题。在应用场景上,无论是Jupyter Notebook中的交互探索、自动化报告的批量生成,还是满足严格出版要求的插图制作,都需要掌握对应的尺寸调整策略。本文聚焦于matplotlib中的figsize参数、rcPa

weixin_30899023的博客 328

solr快速上手:整合spring-data-solr实现客户端操作(十)

首先如果你还不知道spring-data相关工具包如何查看官方文档的,这里给大家统一说明一下1、spring-data的所有文档都可以在这个路径下看到2、找到solr,点击进去3、选择docs,即文档,然后选择当前版本current,如果你要直接查看指定版本的也可根据版本号访问4、进入后选择reference,再选择html,即可进入官方说明文档spring-data-solr官方文档一定要善用官方文档,这可以帮助我们少走很多弯路。

55555的博客 1626

两点调制原理以及RF DAC和PLL SDM两条输入路径理解

特性数据本质原始数字比特流 (0/1)平滑后的预失真波形数据连接对象Σ-Δ调制器 (SDM)的小数输入RF DAC在系统中的角色主调制路径:通过改变PLL分频比产生频率偏移辅助补偿路径:通过RF DAC产生补偿电压,校正PLL失真可否加入延时可以且必须。用于数字时序对齐,对性能无影响。绝对不可以。会导致补偿失配,严重破坏信号频谱。功能目标实现数字域的频率调制确保模拟域的波形和频谱完美因此,在您所描述的这种先进发射机架构中,2-point数据是数字指令,送给SDM;

m0_49540263的博客 604

EMB电子机械制动系统和EHB电子液压制动系统控制功能的对比

EMB电子机械制动系统相比EHB液压制动系统具有显著优势:响应速度更快(<100ms)、控制精度更高(±2N·m)、能实现单轮独立控制,支持0.1%级制动力调节。在ABS、ESC等安全功能上表现更优,制动平顺性和NVH性能更好,同时提升能量回收效率15%-20%。特别适合智能驾驶需求,可使AEB等系统响应时间缩短50ms,紧急制动距离减少1米以上。EMB系统完美契合高阶自动驾驶对快速响应和精准控制的要求。

m0_59012156的博客 885

solr教程

先拿出一条配置来看一下认识一下这些属性name:域名type:域的类型,必须匹配类型,不然会报错indexed:是否要作索引stored:是否要存储required:是否必填,一般只有id才会设置multiValued:是否有多个值,如果设置为多值,里面的值就采用数组的方式来存储,比如商品图片地址(大图,中图,小图等)

精选资讯文章 2372

单稳态触发器Multisim电路仿真——硬件工程师笔记

本文系统介绍了单稳态触发器的基础知识及其实现方式。主要内容包括:1)单稳态触发器的工作原理、电路结构、特点及应用;2)555定时器实现单稳态触发器的配置及工作过程;3)使用反相器和与非门实现积分型和微分型单稳态触发器的电路结构及工作原理。文章详细阐述了各种实现方式的特性、应用场景及设计考虑,为硬件工程师提供了实用的电路设计参考。最后还附有相关笔试面试题链接,便于读者进一步学习扩展。

XU157303764的博客 1875

Solr 全文搜索

Solr 全文搜索

liululee的博客 1003

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

JavaEE进阶——全文检索之Solr7.4服务器

I. Solr Solr简介 Solr是Apache的顶级开源项目,使用java开发 ,基于Lucene的全文检索服务器。 Solr比Lucene提供了更多的查询语句,而且它可扩展、可配置,同时它对Lucene的性能进行了优化。 Solr的全文检索流程 索引流程: Solr客户端(浏览器、java程序)可以向Solr服务端发送POST请求,请求内容是包含Field等信息的一个xml文...

等一杯咖啡的博客 7383

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

java 商城 全文搜索_利用solr实现商品的搜索功能

后期补充:为什么要用solr服务,为什么要用luncence?问题提出:当我们访问购物网站的时候,我们可以根据我们随意所想的内容输入关键字就可以查询出相关的内容,这是怎么做到呢?这些随意的数据不可能是根据数据库的字段查询的,那是怎么查询出来的呢,为什么千奇百怪的关键字都可以查询出来呢?答案就是全文检索工具的实现,luncence采用了词元匹配和切分词。举个例子:北京天安门------luncenc...

weixin_36298146的博客 892

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

java商品搜索功能_利用solr实现商品的搜索功能(实例讲解)

后期补充:为什么要用solr服务,为什么要用luncence?问题提出:当我们访问购物网站的时候,我们可以根据我们随意所想的内容输入关键字就可以查询出相关的内容,这是怎么做到呢?这些随意的数据不可能是根据数据库的字段查询的,那是怎么查询出来的呢,为什么千奇百怪的关键字都可以查询出来呢?答案就是全文检索工具的实现,luncence采用了词元匹配和切分词。举个例子:北京天安门------luncenc...

weixin_39806948的博客 1011

FlyCms全文检索实现原理:Solr索引设计与搜索代码深度解析

FlyCms 是一款基于 Spring Boot + MyBatis + MySql + Solr + Ehcache 架构的完全开源问答社区建站程序。在 FlyCms 中,**全文检索**并非使用 MySQL 的模糊查询,而是交给独立的 Solr 搜索引擎完成——这保证了问答、文章、分享三种内容在百万级数据下的毫秒级响应。本文将深入拆解 **FlyCms 全文检索实现原理**,从 **Solr

gitblog_00094的博客 804

Solr/Solrj初探

Solr/Solrj初探   一、solr简介(摘自[开源中国])   Apache Solr (读音: SOLer) 是一个开源的搜索服务器。Solr使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。Apache Solr 中存储的资源是以 Document 为对象进行存储的。每个文档由一系列的 Field 构成,每个 Field 表示资源的一个属性。S

技海拾贝 1039

Solr全文检索

什么是solr: solr是一个apache的全文检索引擎系统, 就是个war包, 部署到Tomcat下就可以独立运行, 我们使用它的客户端工具包 solrj 来远程调用solr服务器, 完成对索引库的操作(对索引库的添加修改删除, 查询) solr底层使用lucene编写。 Lucene是一个全文检索引擎工具包,它不是一个完整的全文检索应用 而Solr的目标是打造一款企业级的搜索引擎系统 s...

Rhin0cer0s的博客 545

solr的安装与solrJ的使用-java版

solrJ的使用 Solr是一个全文检索服务器,只需要进行配置就可以实现全文检索服务。   1、solr的安装及配置 需要把solr服务器安装到linux环境:     第一步:安装linux、jdk、tomcat。         jdk的安装:上传jdk的压缩包到linux上                             解压jdk                  ...

weixin_40493969的博客 311

全文检索solr(五)Solrj的使用

什么是solrj solrj是访问Solr服务的java客户端,提供索引和搜索的请求方法,如下图: Solrj和图形界面操作的区别就类似于数据库中使用jdbc和mysql客户端的区别一样。 需求 使用solrj调用solr服务实现对索引库的增删改查操作。 环境准备 Solr:4.10.3 Jdk环境:1.7 IDE环境:Eclipse Mars2 工程搭建 创建j...

qq_35670694的博客 338

全文搜索技术 Lucene & solr & es (二)Solr(7.7.1)

学习视频地址:https://www.bilibili.com/video/av45567492?from=search&seid=14848044148453483902 本篇博客是基于此学习视频以及课程笔记进行学习 壹、Solr介绍 1、什么是solr Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。 用户可以通过HTTP...

qq_41965731的博客 2075

【Lucene&Solr】Solr实现全文检索

一、Solr是什么 Solr 是Apache下的一个顶级开源项目,采用Java开发,可以独立运行在Jetty、Tomcat等这些Servlet容器中,它是基于Lucene的全文搜索服务器。Lucene与Solr的区别如下: Lucene是一个开放源代码的全文检索引擎工具包,它不是一个完整的全文检索引擎,但提供了完整的查询引擎和索引引擎,目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者以Lucene为基础构建全文检索引擎。 Solr的目标是打造一款企业级的搜索引擎系

景谦Nice的博客 591

全文检索solr(一)Solr介绍

目录 什么是solr Solr和Lucene的区别 solr的作用 和solr同类型技术 为何要使用全文检索技术 什么是solr 说法一:solr是apache下的一个全文检索引擎系统, 本身就是一个war包, 一个做好的项目, 可以放入tomcat中直接运行使用.底层使用lucene编写 说法二:Solr 是Apache下的一个顶级开源项目,采用Java开...

qq_35670694的博客 499
上一篇: 全文搜索服务器:SOLR安装与应用
下一篇: 全文搜索服务器Solr实例demo
Y叔输得起
博客等级 码龄16年 15粉丝 42原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值