(五)solr7.1.0之solrJ的使用

(五)solr7.1.0之solrJ的使用

下面是solr7的官网API介绍:html

网页翻译的不是很准确,只能了解个大概,基本能获取以下信息:java

1、构建和运行SolrJ应用程序

  对于用Maven构建的项目, pom.xml配置: mysql

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

若是不用maven构建项目,只须要将solr-solrj-7.1.0.jar 和 dist/solrj-lib目录中的依赖包放入到工程中。 sql

2、solr7 API

   在solr5系以后跟solr4最大的区别是被发布成了一个独立的应用。而再也不须要tomcat等容器。在其内部集成了jetty服务器,他能够经过bin目录的脚本直接运行启动。solr5有两种运行模式,独立模式和云模式,独立模式是以core来管理,云模式是以collection来管理。apache

 

  SolrClient是一个抽象类,下边有不少被实现的子类,HttpSolrClient是通用客户端。 能够与一个Solr节点直接通讯。),数组

  LBHttpSolrClient,CloudSolrClient,ConcurrentUpdateSolrClient缓存

  HttpSolrClient的建立需要用户指定一个或多个Solr基础URL,而后客户端使用Solr发送HTTP请求。 tomcat

  1. 一个URL的路径指向一个特定的核心或集合(例如, http://hostname:8983/solr/core1 )。当核心或集合中指定基础的URL,后续请求由客户机不须要测量影响集合。 然而,客户端是有限的核心/集合、发送请求,不能发送请求到任何其余实例。 服务器

  2. 一个URL指向根Solr路径(例如, http://hostname:8983/solr )。 当没有指定核心或集合的基URL,能够请求任何核心/收集,但受影响的核心/必须指定集合的全部请求。 app

通常来讲,若是你的 SolrClient 只会被用在一个核心/收集,包括实体的路径是最方便的。 须要更多的灵活性,收集/核心应该被排除在外。

一、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();

 注意:solr5之后URL指向自定义核心的名称,如实例名称是core1,那么URL为http://127.0.0.1:8080/solr/core1

二、solrJ之查询

SolrClient有不少quary() 查询方法用于从solr中获取结果,这些方法都须要一个SolrParams 类型的参数,该对象能够封装任意的查询参数。和每一个方法输出 QueryResponse 一个包装器,能够用来访问结果文档和其余相关的元数据。

    /** * 查询 * @throws Exception */ @Test public void querySolr() throws Exception{ //[1]获取链接 // HttpSolrClient client= new HttpSolrClient.Builder("http://127.0.0.1:8080/solr/core1").build();
        String solrUrl = "http://127.0.0.1:8080/solr/core1"; //建立solrClient同时指定超时时间,不指定走默认配置
        HttpSolrClient client = new HttpSolrClient.Builder(solrUrl) .withConnectionTimeout(10000) .withSocketTimeout(60000) .build(); //[2]封装查询参数
        Map<String, String> queryParamMap = new HashMap<String, String>(); queryParamMap.put("q", "*:*"); //[3]添加到SolrParams对象
        MapSolrParams queryParams = new MapSolrParams(queryParamMap); //[4]执行查询返回QueryResponse
        QueryResponse response = client.query(queryParams); //[5]获取doc文档
        SolrDocumentList documents = response.getResults(); //[6]内容遍历
        for(SolrDocument doc : documents) { System.out.println("id:"+doc.get("id") +"\tproduct_name:"+doc.get("product_name") +"\tproduct_catalog_name:"+doc.get("product_catalog_name") +"\tproduct_number:"+doc.get("product_number") +"\tproduct_price:"+doc.get("product_price") +"\tproduct_picture:"+doc.get("product_picture")); } client.close(); }

SolrParams 有一个 SolrQuery 子类,它提供了一些方法极大地简化了查询操做。下面是 SolrQuery示例代码 :

     /** * 二、使用 SolrParams 的子类 SolrQuery,它提供了一些方便的方法,极大地简化了查询操做。 * @throws Exception */ @Test public void querySolr2() throws Exception{ //[1]获取链接 // HttpSolrClient client= new HttpSolrClient.Builder("http://127.0.0.1:8080/solr/core1").build();
            String solrUrl = "http://127.0.0.1:8080/solr/core1"; //建立solrClient同时指定超时时间,不指定走默认配置
            HttpSolrClient client = new HttpSolrClient.Builder(solrUrl) .withConnectionTimeout(10000) .withSocketTimeout(60000) .build(); //[2]封装查询参数
            SolrQuery query = new SolrQuery("*:*"); //[3]添加须要回显得内容
            query.addField("id"); query.addField("product_name"); query.setRows(20);//设置每页显示多少条 //[4]执行查询返回QueryResponse
            QueryResponse response = client.query(query); //[5]获取doc文档
            SolrDocumentList documents = response.getResults(); //[6]内容遍历
            for(SolrDocument doc : documents) { System.out.println("id:"+doc.get("id") +"\tproduct_name:"+doc.get("product_name") +"\tname:"+doc.get("name") +"\tproduct_catalog_name:"+doc.get("product_catalog_name") +"\tproduct_number:"+doc.get("product_number") +"\tproduct_price:"+doc.get("product_price") +"\tproduct_picture:"+doc.get("product_picture")); } client.close(); }

三、用solrJ建立索引

   添加索引使用SolrClient的add()方法

    /** * 添加 * @throws SolrServerException * @throws IOException */ @Test public void solrAdd() throws Exception{ //[1]获取链接 // HttpSolrClient client= new HttpSolrClient.Builder("http://127.0.0.1:8080/solr/core1").build();
            String solrUrl = "http://127.0.0.1:8080/solr/core1"; //建立solrClient同时指定超时时间,不指定走默认配置
            HttpSolrClient client = new HttpSolrClient.Builder(solrUrl) .withConnectionTimeout(10000) .withSocketTimeout(60000) .build(); //[2]建立文档doc
            SolrInputDocument doc = new SolrInputDocument(); //[3]添加内容
            String str = UUID.randomUUID().toString(); System.out.println(str); doc.addField("id", str); doc.addField("name", "Amazon Kindle Paperwhite"); //[4]添加到client
            UpdateResponse updateResponse = client.add(doc); System.out.println(updateResponse.getElapsedTime()); //[5] 索引文档必须commit
 client.commit(); }

   在正常状况下,文档应该在更大的批次,索引,而不是一次一个的进行索引。 它也建议使用Solra Solr管理员提交文档€™时设置为autocommit自动提交,而不是使用显式的 commit() 调用。

四、solrJ之单个id 的删除索引

 /** * 四、单个id 的删除索引 */ @Test public void solrDelete() throws Exception{ //[1]获取链接
    HttpSolrClient client = Constant.getSolrClient(); //[2]经过id删除
    client.deleteById("30000"); //[3]提交
 client.commit(); //[4]关闭资源
 client.close(); } 

五、solrJ之多个id 的list集合 删除索引

 /** * 五、多个id 的list集合 删除索引 */ @Test public void solrDeleteList() throws Exception{ //[1]获取链接
        HttpSolrClient client = Constant.getSolrClient(); //[2]经过id删除
        ArrayList<String> ids = new ArrayList<String>(); ids.add("30000"); ids.add("1"); client.deleteById(ids); //[3]提交
 client.commit(); //[4]关闭资源
 client.close(); }

 六、Java对象绑定

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

先查看一下配置:

solrconfig.xml配置

<requestHandler name="/dataimport" class="solr.DataImportHandler"> <lst name="defaults"> <!--数据源配置文件所在路径--> <str name="config">./data-config.xml</str> </lst> </requestHandler>

 data-config.xml配置

<?xml version="1.0" encoding="UTF-8" ?>  
<dataConfig>   
     <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/solrdata" user="root" password="root"/>   
    <document>   
         <entity name="product" query="select pid,name,catalog,catalog_name,price,number,description,picture from products">
             <field column="pid" name="id"/>
             <field column="name" name="p_name"/>
             <field column="catalog_name" name="p_catalog_name"/>
             <field column="price" name="p_price"/>
             <field column="number" name="p_number"/>
             <field column="description" name="p_description"/>
             <field column="picture" name="p_picture"/>
         </entity>   
    </document>        
</dataConfig>  

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设置 集合或数组类型如

private String[] content;//多值,对应 multiValued="true"

注意:solr4版本的field的type属性的基本数据类型到solr7的变化

详细内容参照solr-7.1.0\example\example-DIH\solr\db\conf\目录下的managed-schema

string string
boolean boolean
int pint
double pdouble
long plong
float pfloat
date pdate

首先须要建立对象Product,字段必须与schema.xmlmanaged-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的fieldtype属性 javaBean 属性类型
string String
boolean Boolean
pint Integer
pdouble Double
plong Long
pfloat Float
pdate Date
 
product实体对象:
package junit; import org.apache.solr.client.solrj.beans.Field; public class Product { /** * 商品编号 */ @Field private String id; /** * 商品名称 */ @Field private String p_name; /** * 商品分类名称 */ @Field private String p_catalog_name; /** * 价格 */ @Field private Float p_price; /** * 数量 */ @Field private Long p_number; /** * 图片名称 */ @Field private String p_picture; /** * 商品描述 */ @Field private String p_description; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getP_name() { return p_name; } public void setP_name(String p_name) { this.p_name = p_name; } public String getP_catalog_name() { return p_catalog_name; } public void setP_catalog_name(String p_catalog_name) { this.p_catalog_name = p_catalog_name; } public Float getP_price() { return p_price; } public void setP_price(Float p_price) { this.p_price = p_price; } public Long getP_number() { return p_number; } public void setP_number(Long p_number) { this.p_number = p_number; } public String getP_picture() { return p_picture; } public void setP_picture(String p_picture) { this.p_picture = p_picture; } public String getP_description() { return p_description; } public void setP_description(String p_description) { this.p_description = p_description; } //空参数构造 public Product() {} //满参数构造 public Product(String id, String p_name, String p_catalog_name, Float p_price, Long p_number, String p_picture, String p_description) { super(); this.id = id; this.p_name = p_name; this.p_catalog_name = p_catalog_name; this.p_price = p_price; this.p_number = p_number; this.p_picture = p_picture; this.p_description = p_description; } }

4.一、在应用中使用:

 (1)Java对象绑定,经过对象建立索引
      /** * 六、Java对象绑定,经过对象建立索引 */ @Test public void addBean() throws Exception{ //[1]获取链接 // HttpSolrClient client= new HttpSolrClient.Builder("http://127.0.0.1:8080/solr/core1").build();
            String solrUrl = "http://127.0.0.1:8080/solr/core1"; //建立solrClient同时指定超时时间,不指定走默认配置
            HttpSolrClient client = new HttpSolrClient.Builder(solrUrl) .withConnectionTimeout(10000) .withSocketTimeout(60000) .build(); //[3]建立对象
            Product product = new Product(); product.setId("30000"); product.setP_name("测试商品名称"); product.setP_catalog_name("测试商品分类名称"); product.setP_price(399F); product.setP_number(30000L); product.setP_description("测试商品描述"); product.setP_picture("测试商品图片.jpg"); //[4]添加对象
            UpdateResponse response = client.addBean(product); //[5]提交操做
 client.commit(); //[6]关闭资源
 client.close(); } 
查看添加的内容以下:

  

(2)Java对象绑定,经过对象索引查询

  搜索时能够经过QueryResponse的getbean()方法将结果直接转换成bean对象:

     /** * 七、Java对象绑定,经过对象查询索引 */ @Test public void queryBean() throws Exception{ //[1]获取链接 // HttpSolrClient client= new HttpSolrClient.Builder("http://127.0.0.1:8080/solr/core1").build();
            String solrUrl = "http://127.0.0.1:8080/solr/core1"; //建立solrClient同时指定超时时间,不指定走默认配置
            HttpSolrClient client = new HttpSolrClient.Builder(solrUrl) .withConnectionTimeout(10000) .withSocketTimeout(60000) .build(); //[2]建立SolrQuery对象
            SolrQuery query = new SolrQuery("*:*"); //添加回显的内容
            query.addField("id"); query.addField("p_name"); query.addField("p_price"); query.addField("p_catalog_name"); query.addField("p_number"); query.addField("p_picture"); query.setRows(200);//设置每页显示多少条 //[3]执行查询返回QueryResponse
            QueryResponse response = client.query(query); //[4]获取doc文档
            List<Product> products = response.getBeans(Product.class); //[5]遍历
            for (Product product : products) { System.out.println("id:"+product.getId() +"\tp_name:"+product.getP_name() +"\tp_price:"+product.getP_price() +"\tp_catalog_name:"+product.getP_catalog_name() +"\tp_number:"+product.getP_number() +"\tp_picture:"+product.getP_picture() ); } //[6]关闭资源
 client.close(); }  

 查询结果:

(3)solrJ之经过deleteByQuery删除索引

     /**
         * 八、经过deleteByQuery删除索引
         */ @Test
public void deleteBean() throws Exception{ //[1]获取链接 // HttpSolrClient client= new HttpSolrClient.Builder("http://127.0.0.1:8080/solr/core1").build(); String solrUrl = "http://127.0.0.1:8080/solr/core1"; //建立solrClient同时指定超时时间,不指定走默认配置 HttpSolrClient client = new HttpSolrClient.Builder(solrUrl) .withConnectionTimeout(10000) .withSocketTimeout(60000) .build(); //[2]执行删除 client.deleteByQuery("id:100"); //[3]提交操做 client.commit(); //[4]关闭资源
client.close(); }


下面是官网API的对字段类型定义的说法

 字段类型定义和属性

managed-schema文件中的字段类型定义

① 上面的示例中的第一行包含字段类型名称 name="text_general",实现类的名称class="solr.TextField"

其他的定义是关于对field分析、描述 理解分析、分词器和过滤器

实现类负责确保字段是正确的被处理。 在managed-schema中的类名字符串 solr org.apache.solr.schema org.apache.solr.analysis的缩写。如: solr.TextField 真的是 org.apache.solr.schema.TextField

字段类型属性

field type的class属性决定了大多数字段类型的行为,但可选属性也能够被定义。例如,下面的日期字段类型定义两个属性的定义sortMissingLastomitNorms

<fieldType name="date" class="solr.DatePointField" sortMissingLast="true" omitNorms="true"/>

能够为一个给定的指定的属性字段类型分为三大类:

  • 特定的字段类型的class属性。
  • Solr支持任何字段类型。

  • 能够指定的字段类型所继承的字段,使用这个类型而不是默认的行为。

通常属性

  • 这些都是通常的属性字段

    name
  • fieldType的name。 这个值被用于field定义的“type”属性。 强烈建议名称只包含字母数字或下划线字符,而不是从一个数字开始。 这不是目前严格执行。

  class

class的name,用于存储和索引的数据类型。 请注意,您可能包括类名前面加上“solr。 ”,Solr搜索会自动找出哪些包类,因此 solr.TextField 将工做。

若是您使用的是第三方的类,你可能须要一个彻底限定的类名。彻底限定的等效 solr.TextField org.apache.solr.schema.TextField

positionIncrementGap

对于多值字段,指定多个值之间的距离,防止虚假的短语匹配。

autoGeneratePhraseQueries

对于文本字段。 若是 true,Solr自动生成短语查询相邻。 若是false 、terms 必须括在双引号被视为短语。

enableGraphQueries

对于text fields,查询时适用 sow = false (这是默认的 sow 参数)。 使用 true 、默认字段类型的查询分析器包括graph-aware过滤器,例如, Synonym Graph Filter 和 Word Delimiter Graph Filter

使用 false字段类型的查询分析器能够匹配文档包括过滤器,当一些令牌丢失,例如, Shingle Filter

docValuesFormat

定义了一个定制的 DocValuesFormat 用于这种类型的字段。 这就要求一个感知的编解码器,如 SchemaCodecFactory 已经配置在 xml

postingsFormat

定义了一个定制的 PostingsFormat 用于这种类型的字段。 这就要求一个感知的编解码器,如 SchemaCodecFactory 已经配置在 xml

 字段默认属性

这些属性能够指定字段类型,或对我的领域覆盖提供的字段类型的值。

每一个属性的默认值取决于底层 FieldType 类,进而可能取决于 版本 的属性<schema/> 。 下表包含了大部分的默认值 FieldType Solr提供了实现,假设 schema.xml 声明 version = " 1.6 "

属性 描述 默认值
indexed 若是true,字段的值可用于查询来检索匹配的文档。
true or false
 true
stored 若是true,field的实际值能够经过查询检索。 true or false  true
docValues 若是true,字段的值将用于 DocValues 结构。 true or false  false
sortMissingFirst sortMissingLast  控制文档的位置,当分类字段不存在时。 true or false  false
multiValued
 若是是true,代表一个文档可能包含多个值的字段类型。 true or false  false
omitNorms 若是是true,省略了与这个领域相关的规范(这个禁用长度归一化的领域,并节省一些内存)。 全部原始默认值为true(non-analyzed)字段类型,如整数、浮点数、数据、布尔值和字符串。 只有全文字段或字段须要规范。 true or false  *
omitTermFreqAndPositions 若是是true,省略了词频率、位置和有效载荷从检索条数的field。 这是一个性能提高不须要这些信息的field。 它还能够减小所需的存储空间索引。 依赖于位置的查询字段上发布这个选项将默默地找不到文件。 该属性默认为适用于全部字段类型非 text fields true or false  *
omitPositions 相似于 omitTermFreqAndPositions 但保留词频率信息。 true or false  *
termVectors termPositions termOffsets termPayloads 这些选项指示Solr保持完整任期为每一个文档向量,可选地包括位置、抵消和负载信息为每一个术语出如今这些向量。 这些能够用来加速高亮显示和其余辅助功能,但对大量成本指数的大小。 他们不是典型的使用Solr的必要条件。 true or false  false
required 没有这个字段的值命令Solr拒绝任何试图添加一个文档。 该属性默认值为false。 true or false  false
useDocValuesAsStored  若是字段有 docValues 启用时,设置为true将容许返回字段,就好像它是一个存储字段(即便它stored=false)当匹配€œ * 一个€在一个 fl参数 true or false  true
large
 多数的field老是懒加载和当文档中占用空间缓存的实际值 < 512 kb。 这个选项须要 stored="true"multiValued="false"。它是用于field有很是大的价值,这样他们不会在内存中缓存。 true or false  false

包含在Solr中字段类型

下表列出了在Solr可用字段类型。 的 org.apache.solr.schema 包包括全部表中列出的类。

   因为工做缘由,下边的描述还有待查证。

class 描述
BinaryField  
BoolField  
CollationField  
CurrencyField  
CurrencyFieldType  
DateRangeField  
DatePointField  
DoublePointField  
ExternalFileField  
EnumField  
EnumFieldType  
FloatPointField  
ICUCollationField  
IntPointField  
LatLonPointSpatialField  
LatLonType  
LongPointField  
PointType  
PreAnalyzedField  
RandomSortField  
SpatialRecursivePrefixTreeFieldType  
StrField  
TextField  
TrieDateField 弃用 。 使用DatePointField代替。
TrieDoubleField 弃用 。 使用DoublePointField代替。
TrieFloatField 弃用 。 使用FloatPointField代替。
TrieIntField 弃用 。 使用IntPointField代替。
TrieLongField 弃用 。 使用LongPointField代替。
TrieField

弃用 。 这个field须要 type 参数定义特定类使用Trie* field;使用一个适当field type代替。

UUIDField
相关文章
相关标签/搜索