Riak Search功能使用

要使用Riak的search功能需要很複雜的步驟。根據官方文檔的描述,要使用search功能需要經過下面的步驟:
1. 創建一個自定義的schema。如果不創建,可以使用自定義的schema。官方推薦在實際產品中使用自定義的schema。
2. 創建一個index和某個schema關聯。如果不指定特定的schema,則使用系統默認的schema。
3. 關聯索引。
一種是直接給一個bucket type指定一個索引,這樣所有屬於這個bucket type的bucket都會使用這個索引。(官方推薦使用這種)
另一種是給每一個bucket指定一個單獨的索引。
另外也可以給已有的bucket指定一個索引。如果已有的bucket在默認的bucket type下面,那麼可以單獨給這個bucket指定一個索引。

package com.dasudian.dsdb.demo;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;

import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.commands.kv.DeleteValue;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.api.commands.kv.StoreValue;
import com.basho.riak.client.api.commands.search.StoreIndex;
import com.basho.riak.client.api.commands.search.StoreSchema;
import com.basho.riak.client.core.RiakCluster;
import com.basho.riak.client.core.RiakFuture;
import com.basho.riak.client.core.RiakNode;
import com.basho.riak.client.core.operations.SearchOperation;
import com.basho.riak.client.core.query.Location;
import com.basho.riak.client.core.query.Namespace;
import com.basho.riak.client.core.query.RiakObject;
import com.basho.riak.client.core.query.search.YokozunaIndex;
import com.basho.riak.client.core.query.search.YokozunaSchema;
import com.basho.riak.client.core.util.BinaryValue;

public class Search {
    private static String schemaName = "people_schema";
    private static String index = "people_index";
    private static String bucketType = "people_type";
    private static String bucket = "people_bucket";
    private static String key = "people_key";
    private static String data = "{\"name\":\"Jack_Liu\",\"age\":24,\"leader\":false}";
    private static String condtion = "name:Jack*";

    public static void main(String[] args) throws Exception {
        RiakNode node = new RiakNode.Builder().withRemoteAddress("192.168.1.28").withRemotePort(8087).build();
        RiakCluster riakCluster = new RiakCluster.Builder(node).build();
        riakCluster.start();
        RiakClient riakClient = new RiakClient(riakCluster);
        // 1.創建一個自定義的schema
//      createSchema(riakClient);
        // 2.創建一個索引和這個schema關聯
//      createIndex(riakClient);

        // 3.在命令執行下面的兩條命令,創建一個bucket type和這個index關聯
        // riak-admin bucket-type create people_type  '{"props":{"search_index":"people_index"}}'
        // riak-admin bucket-type activate people_type

        store(riakClient);
        get(riakClient);
        // 4. 搜看有沒有數據
        search(riakCluster);

//      delete(riakClient);

        riakCluster.shutdown();
    }

    public static void createSchema(RiakClient client) throws FileNotFoundException, ExecutionException, InterruptedException {
        File xml = new File(Search.class.getClassLoader().getResource("schema.xml").getFile());
        String xmlString = new Scanner(xml).useDelimiter("\\Z").next();
        YokozunaSchema schema = new YokozunaSchema(schemaName, xmlString);
        StoreSchema storeSchemaOp = new StoreSchema.Builder(schema).build();
        client.execute(storeSchemaOp);
    }

    public static void createIndex(RiakClient client) throws ExecutionException, InterruptedException {
        YokozunaIndex famousIndex = new YokozunaIndex(index, schemaName);
        StoreIndex storeIndex = new StoreIndex.Builder(famousIndex).build();
        client.execute(storeIndex);
    }

    public static void store(RiakClient client) throws ExecutionException, InterruptedException {
        Namespace ns = new Namespace(bucketType, bucket);
        String json = "application/json";
        RiakObject liono = new RiakObject().setContentType(json).setValue(BinaryValue.create(data));
        Location lionoLoc = new Location(ns, key);

        StoreValue lionoStore = new StoreValue.Builder(liono).withLocation(lionoLoc).build();
        client.execute(lionoStore);
    }

    public static void get(RiakClient riakClient) throws ExecutionException, InterruptedException {
        Namespace ns = new Namespace(bucketType, bucket);
        Location location = new Location(ns, key);
        FetchValue fv = new FetchValue.Builder(location).build();
        FetchValue.Response response = riakClient.execute(fv);
        for (RiakObject object : response.getValues()) {
            System.out.println(object.getValue());
        }
    }

    public static void search(RiakCluster riakCluster) throws InterruptedException {
        SearchOperation searchOp = new SearchOperation.Builder(BinaryValue.create(index), condtion).build();
        RiakFuture<com.basho.riak.client.core.operations.SearchOperation.Response, BinaryValue> execute = riakCluster
                .execute(searchOp);
        execute.await();
        if (execute.isDone()) {
            if (execute.isSuccess()) {
                List<Map<String, List<String>>> results = searchOp.getNow().getAllResults();
                System.out.println(results);
            } else {
                System.out.println(execute.cause());
            }
        }
    }

    public static void delete(RiakClient riakClient) throws ExecutionException, InterruptedException {
        Namespace ns = new Namespace(bucketType, bucket);
        Location location = new Location(ns, key);
        DeleteValue fv = new DeleteValue.Builder(location).build();
        riakClient.execute(fv);
    }
}

schema文件內容

<?xml version="1.0" encoding="UTF-8" ?>
<schema name="people" version="1.5">
 <fields>
   <!-- 添加自己的index規則。下面3行是自己根據數據的內容來創建的 -->
   <field name="name"   type="string"  indexed="true" stored="true" />
   <field name="age"    type="int"     indexed="true" stored="false" />
   <field name="leader" type="boolean" indexed="true" stored="false" />

   <!-- All of these fields are required by Riak Search -->
   <field name="_yz_id"   type="_yz_str" indexed="true" stored="true"  multiValued="false" required="true"/>
   <field name="_yz_ed"   type="_yz_str" indexed="true" stored="false" multiValued="false"/>
   <field name="_yz_pn"   type="_yz_str" indexed="true" stored="false" multiValued="false"/>
   <field name="_yz_fpn"  type="_yz_str" indexed="true" stored="false" multiValued="false"/>
   <field name="_yz_vtag" type="_yz_str" indexed="true" stored="false" multiValued="false"/>
   <field name="_yz_rk"   type="_yz_str" indexed="true" stored="true"  multiValued="false"/>
   <field name="_yz_rt"   type="_yz_str" indexed="true" stored="true"  multiValued="false"/>
   <field name="_yz_rb"   type="_yz_str" indexed="true" stored="true"  multiValued="false"/>
   <field name="_yz_err"  type="_yz_str" indexed="true" stored="false" multiValued="false"/>

   <dynamicField name="*" type="ignored"  />
 </fields>


 <uniqueKey>_yz_id</uniqueKey>

 <types>
    <!-- YZ String: Used for non-analyzed fields -->
    <fieldType name="_yz_str" class="solr.StrField" sortMissingLast="true" />

    <!-- 添加自己的類型 -->
    <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
    <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
    <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
    <fieldtype name="ignored" stored="false" indexed="false" multiValued="true" class="solr.StrField" />
 </types>
</schema>

想了解更多關於如何創建自定義的schema可以查看官方文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章