solr7之solrJ的使用


solr7的官網API介紹

網頁翻譯的不是很准確,只能了解個大概,基本能獲取如下信息:

一、構建和運行SolrJ應用程序

  對於用Maven構建的項目, pom.xml配置:

<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目錄中的依賴包放入到工程中。

二、solr7 API

   在solr5系之后跟solr4最大的區別是被發布成了一個獨立的應用。而不再需要tomcat等容器。在其內部集成了jetty服務器,他可以通過bin目錄的腳本直接運行啟動。solr5有兩種運行模式,獨立模式和雲模式,獨立模式是以core來管理,雲模式是以collection來管理。

 

  SolrClient是一個抽象類,下邊有很多被實現的子類,HttpSolrClient是通用客戶端。 可以與一個Solr節點直接通信。),

  LBHttpSolrClient,CloudSolrClient,ConcurrentUpdateSolrClient

  HttpSolrClient的創建需要用戶指定一個或多個Solr基礎URL,然后客戶端使用Solr發送HTTP請求。

  1. 一個URL的路徑指向一個特定的核心或集合(例如, http://hostname:8983/solr/core1 )。當核心或集合中指定基礎的URL,后續請求由客戶機不需要測量影響集合。 然而,客戶端是有限的核心/集合、發送請求,不能發送請求到任何其他實例。

  2. 一個URL指向根Solr路徑(例如, http://hostname:8983/solr )。 當沒有指定核心或集合的基URL,可以請求任何核心/收集,但受影響的核心/必須指定集合的所有請求。

一般來說,如果你的 SolrClient 只會被用在一個核心/收集,包括實體的路徑是最方便的。 需要更多的靈活性,收集/核心應該被排除在外。

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

 注意:solr5以后URL指向自定義核心的名稱,如實例名稱是core1,那么URL為http://127.0.0.1:8080/solr/core1

2、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示例代碼 :

/**
         * 2、使用 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();
        }

3、用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() 調用。

4、solrJ之單個id 的刪除索引

/**
  * 4、單個id 的刪除索引
  */
 @Test  
  public void solrDelete() throws Exception{
     //[1]獲取連接
    HttpSolrClient client = Constant.getSolrClient();
    //[2]通過id刪除
    client.deleteById("30000");
    //[3]提交
    client.commit();
    //[4]關閉資源
    client.close();
}      

5、solrJ之多個id 的list集合 刪除索引

/**
   * 5、多個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();
    }

6、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

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;
    }
}

三 在應用中使用:

(1)Java對象綁定,通過對象創建索引

/**
         * 6、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對象:

/**
         * 7、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刪除索引

/**
         * 8、通過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 " 

 

包含在Solr中字段類型

下表列出了在Solr可用字段類型。 的 org.apache.solr.schema 包包括所有表中列出的類。

   由於工作原因,下邊的描述還有待查證。

上面的整理來自博文:https://www.cnblogs.com/gaogaoyanjiu/p/7815558.html

它使用的7.1.0版本。在這里感謝博主的分享。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM