solr的搜索实例

Posted youzhongmin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了solr的搜索实例相关的知识,希望对你有一定的参考价值。

实例

在构建索引库后需要对schema.xml配置文件中添加需要搜索的字段名。

schema.xml配置

<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
    <!-- docValues are enabled by default for long type so we don‘t need to index the version field  -->
    <field name="_version_" type="plong" indexed="false" stored="false"/>
    <field name="_root_" type="string" indexed="true" stored="false" docValues="false" />
    <field name="_text_" type="text_general" indexed="true" stored="false" multiValued="true"/>
    <!--name、phoneType、price字段对应保存的字段名-->
    <field name="name" type="string" indexed="true" stored="true"/>
    <field name="phoneType" type="string" indexed="true" stored="true"/>
    <field name="price" type="string" indexed="true" stored="true"/>

通过SolrJ客户端连接Solr

1、创建实体类Phone

package solrtest;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.apache.solr.client.solrj.beans.Field;
import org.apache.solr.common.SolrInputDocument;

public class Phone {
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	@Field("id")
	private String id;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPhoneType() {
		return phoneType;
	}
	public void setPhoneType(String phoneType) {
		this.phoneType = phoneType;
	}
	public String getPrice() {
		return price;
	}
	public void setPrice(String price) {
		this.price = price;
	}
	@Field(value = "name")
	private String name;
	@Field(value = "phoneType")
	private String phoneType;
	@Field(value = "price")
	private String price;
}

  2、对Solr中的数据进行增删改查

package solrtest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
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 net.sf.json.JSONArray;
import net.sf.json.JSONObject;


public class SolrService {
	private static final String SOLR_PATH = "http://192.168.121.12:8080/solr/core";
	// 实例化solr对象
	private static final HttpSolrClient solrServer = new HttpSolrClient.Builder(SOLR_PATH).
					withConnectionTimeout(100000).withSocketTimeout(1000).build();

	public static void addIndex(Phone phone) throws Exception, IOException {
        // 创建一个文档
        //添加的Field 必须是在schema.xml 中配置了,不然就报错
        // 创建文档2
        solrServer.addBean(phone);
        // 提交
        solrServer.commit();
    }
	
	public static void addIndex(JSONObject jsonObject) throws Exception, IOException {
        // 创建一个文档
		SolrInputDocument doc = new SolrInputDocument();
		doc.addField("name", jsonObject.getString("name"));
		doc.addField("id", UUID.randomUUID().toString());
		doc.addField("phoneType", jsonObject.getString("phoneType"));
		doc.addField("price", jsonObject.getString("price"));
        solrServer.add(doc);
        // 提交
        solrServer.commit();
    }
	
	public static void addIndexs(JSONArray jsonArray) throws Exception, IOException {
		List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
		for(int i=0;i<jsonArray.size();i++){
			JSONObject jsonObject = jsonArray.getJSONObject(i);
			SolrInputDocument doc = new SolrInputDocument();
			doc.addField("name", jsonObject.getString("name"));
			doc.addField("id", UUID.randomUUID().toString());
			doc.addField("phoneType", jsonObject.getString("phoneType"));
			doc.addField("price", jsonObject.getString("price"));
			docs.add(doc);
		}
		solrServer.add(docs);
        // 提交
        solrServer.commit();
	}
	
	public static void addIndexs(List<Phone> phoneList) throws Exception, IOException {
		solrServer.addBeans(phoneList);
		solrServer.commit();
	}
	
	//通过指定的id删除数据
	public void delete(List<String> ids) throws Exception {
        this.solrServer.deleteById(ids);
        this.solrServer.commit(); //提交
    }
	//通过指定的域值删除数据
	public void deleteByField(String fieldName,String fieldValue) throws Exception {
		String query = fieldName + ":" + fieldValue;
		this.solrServer.deleteByQuery(query);
	    this.solrServer.commit(); //提交
	    }
	
	//通过指定的域值更新数据
	public void updateByField(String id,String fieldName,String fieldValue) throws Exception {
		SolrInputDocument doc = new SolrInputDocument();
		doc.addField("id", id);
		doc.addField(fieldName, fieldValue);
		this.solrServer.add(doc);
		this.solrServer.commit(); //提交
		}
	//查询索引
	public static void query(String fieldName,String fieldValue, Integer page, Integer rows,String fieldSort) throws Exception {
        //添加查询
        SolrQuery solrQuery = new SolrQuery();
        //查询
        //代表Solr控制界面Query中的p字段 ,查询字符串,这个是必须的。
        //如果查询所有*:* ,根据指定字段查询(Name:张三 AND Address:北京)
        //solrQuery.set(fieldName, fieldValue);
        solrQuery.setQuery(fieldName+":"+fieldValue);
        //代表fq字段 ,(filter query)过虑查询,作用:在q查询符合结果中同时是fq查询符合的,
        //例如:q=Name:张三&fq=CreateDate:[20081001 TO 20091031],找关键字mm,并且CreateDate是20081001
//        solrQuery.addFilterQuery("itemName:yby");
        //指定返回那些字段内容,用逗号或空格分隔多个。
        solrQuery.addField("id,phoneType,price");
        //按照指定的字段排序
        solrQuery.setSort(fieldSort, ORDER.asc);
        // 设置分页 start=0就是从0开始,,rows=5当前返回5条记录,第二页就是变化start这个值为5就可以了。
        solrQuery.setStart((Math.max(page, 1) - 1) * rows);
        solrQuery.setRows(rows);
       // 设置高亮
        solrQuery.setHighlight(true); // 开启高亮组件
        solrQuery.addHighlightField("id");// 高亮字段
        solrQuery.setHighlightSimplePre("<em>");// 标记,高亮关键字前缀
        solrQuery.setHighlightSimplePost("</em>");// 后缀
        //获取查询结果
        QueryResponse response = solrServer.query(solrQuery);
        //获取查询到的文档
        SolrDocumentList docs = response.getResults();
        //查询到的条数
        long cnt = docs.getNumFound();
        System.out.println("查询到的条数	"+cnt);
        //获取查询结果
        for(SolrDocument doc :docs) {
            String id = doc.get("id").toString();
            System.out.printf("%s
",id);
            String phoneType = doc.get("phoneType").toString();
            System.out.printf("%s
",phoneType);
        }
    }
}

客户端详解

1、solrJ客户端实例创建并设置连接超时时间

final String solrUrl = "http://127.0.0.1:8080/solr";
//创建solrClient同时指定超时时间,不指定走默认配置
HttpSolrClient build = new HttpSolrClient.Builder(solrUrl)
                .withConnectionTimeout(10000)
                .withSocketTimeout(60000)
                .build();

不同solr版本solrj 的创建方式有所不同

//solr4创建方式
//SolrServer solrServer = new HttpSolrServer("http://127.0.0.1:8080/solr");  
//solr5创建方式,在url中指定core名称:core1
//HttpSolrClient solrServer=new HttpSolrClient("http://127.0.0.1:8080/solr/core1");
//solr7创建方式,在url中指定core名称:core1
HttpSolrClient solrServer= new HttpSolrClient.Builder("http://127.0.0.1:8080/solr/core1").build();

2、Java对象绑定

SolrJ提供两个有用的接口,UpdateResponse 和 QueryResponse,它们可以很方便的处理特定域的对象,可以使您的应用程序更容易被理解。SolrJ支持通过@Field注解隐式转换文档与任何类每个实例变量在Java对象可以映射到一个相应的Solr字段中,使用 field注解

managed-schema文件配置

<!--配置ik分词器-->
  <fieldType name="text_ik" class="solr.TextField">
    <analyzer type="index" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
    <analyzer type="query" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
  </fieldType>
  <!--配置ik分词器-->
  <field name="name_ik" type="text_ik" indexed="true" stored="true"/>
  <!--项目中的字段-->
    <field name="p_name" type="text_ik" indexed="true" stored="true"/>
    <field name="p_catalog_name" type="string" indexed="true" stored="true"/>
    <field name="p_price" type="pfloat" indexed="true" stored="true"/>
    <field name="p_number" type="plong" indexed="true" stored="true"/>
    <field name="p_description" type="text_ik" indexed="true" stored="true"/>
    <field name="p_picture" type="string" indexed="false" stored="true"/>
    
    <!--关键词  定义复制域字段,将商品名称和商品描述都复制到 product_keywords这一个字段上-->
    <field name="p_keywords" type="text_ik" indexed="true" stored="false" multiValued="true" />
    <copyField source="p_name" dest="p_keywords" />
    <copyField source="p_description" dest="p_keywords" />

  其中 indexed="true" 表示开启索引(当字段不需要被检索时,最好不要开启索引,) stored="true"表示存储原来数据(当字段不被检索,而只是需要通过其他字段检索而获得时,要设为true)  multiValued="true" 表示返回多值,如一个返回多个content,此时要在java代码中把 content设置 集合或数组类型。

首先需要创建对象Product,字段必须与schema.xml或managed-schema配置文件的field的一致,该配置文件中必需有这个field,不然会报错。

①字段写错:查询时不报错,查不出来想要的数据,添加时创建的索引字段也不是自己想要的field。

②字段type类型不一致:Caused by: java.long.IllegalArgementException:Can not set java.lang.Integer field junit.Product.id to java.long.String。

以上是关于solr的搜索实例的主要内容,如果未能解决你的问题,请参考以下文章

Hue, Solr - 搜索词的自动填充

[项目构建 七]babasport 商品上架及Solr使用实例.

solr的搜索实例

Solr的原理及在项目中的使用实例

如何使用单个 solr 实例索引和搜索位于同一数据源中的两个不同表或 Solr 模板字段无法正常工作

02 Apache Solr: 概览 Solr在信息系统架构中的位置