天天看點

solr7之solrJ的使用

solr7的官網API介紹

solr7之solrJ的使用

網頁翻譯的不是很準确,隻能了解個大概,基本能擷取如下資訊:

一、建構和運作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之solrJ的使用

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

solr7之solrJ的使用
solr7之solrJ的使用

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();
        }      
檢視添加的内容如下:      
solr7之solrJ的使用

(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();  
        }      
solr7之solrJ的使用

(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檔案中的字段類型定義

solr7之solrJ的使用

① 上面的示例中的第一行包含字段類型名稱

 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屬性

決定了大多數字段類型的行為,但可選屬性也可以被定義。例如,下面的日期字段類型定義兩個屬性的定義

,sortMissingLast

omitNorms 

<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 " 

solr7之solrJ的使用

包含在Solr中字段類型

下表列出了在Solr可用字段類型。 的 

org.apache.solr.schema 

包包括所有表中列出的類。

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

solr7之solrJ的使用

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

它使用的7.1.0版本。在這裡感謝部落客的分享。

繼續閱讀