分布式搜索Elasticsearch——集成paoding

先做个记录,研究出来了,不记下来下次就不知道怎么处理了。

为es安装paoding插件

首先你得安装paoding插件,进入%ES_HOME%/bin,执行下列代码:

plugin -install medcl/elasticsearch-analysis-paoding/1.0.0
接下来,在https://github.com/medcl/elasticsearch-analysis-paoding下载paoding解析插件,解压后,把elasticsearch-analysis-paoding-master\config\下的paoding文件夹放置到%ES_HOME%/config下。


在java代码中使用es和paoding插件

1. 在项目中导入es及es-paoding的包;

2. 将paoding文件夹复制到根目录下的config下;

3. 在src目录下建立一个elasticsearch.yml文件,使其内容如下所示:

index:  
  analysis:                     
    analyzer:        
      paoding:  
          alias: [paoding_analyzer]  
          type: org.elasticsearch.index.analysis.PaodingAnalyzerProvider 
4. java代码,当你只需要为一个字段建立索引,并通过这个字段查询时代码如下所示:

import java.util.Iterator;
import java.util.Map;

import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.indices.IndexAlreadyExistsException;
import org.elasticsearch.node.Node;
import org.elasticsearch.node.NodeBuilder;
import org.elasticsearch.search.SearchHit;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * <p>
 * MyTest.java
 * </p>
 * <p>
 * </p>
 * 
 * @author $Author: Geloin $
 * @version $Revision: V5.1 $
 */
public class MyTest {

    private static Node node;

    @BeforeClass
    public static void beforeClass() {
        node = NodeBuilder.nodeBuilder().node();
    }

    /**
     * 
     * <p>
     * 创建索引
     * </p>
     * @author Geloin
     * Created [2012-12-29 下午5:38:22]
     * @throws Exception
     */
    @Test
    public void createIndex() throws Exception {

        Client client = node.client();
        try {

            try {
                // 预定义一个索引
                client.admin().indices().prepareCreate("app").execute().actionGet();
                
                // 定义索引字段属性
                XContentBuilder mapping = XContentFactory.jsonBuilder().startObject();
                mapping = mapping.startObject("title")
                                // 创建索引时使用paoding解析
                                .field("indexAnalyzer", "paoding")
                                // 搜索时使用paoding解析
                                .field("searchAnalyzer", "paoding")
                                .field("store", "yes")
                          .endObject();
                mapping = mapping.endObject();

                PutMappingRequest mappingRequest = Requests.putMappingRequest("app").type("article").source(mapping);
                client.admin().indices().putMapping(mappingRequest).actionGet();
            }
            catch (IndexAlreadyExistsException e) {
                System.out.println("索引库已存在");
            }

            // 生成文档
            XContentBuilder doc = XContentFactory.jsonBuilder().startObject();
            doc = doc.field("title", "java附魔大师");
            doc = doc.endObject();

            // 创建索引
            IndexResponse response = client.prepareIndex("app", "article", "1").setSource(doc).execute().actionGet();

            System.out.println(response.getId() + "====" + response.getIndex() + "====" + response.getType());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            client.close();
        }
    }

    /**
     * 
     * <p>
     * 查询
     * </p>
     * @author Geloin
     * Created [2012-12-29 下午5:40:55]
     * @throws Exception
     */
    @Test
    public void search() throws Exception {
        Client client = node.client();
        try {
            QueryBuilder qb = QueryBuilders.termQuery("title", "大师");
            SearchResponse scrollResp = client.prepareSearch("app").setSearchType(SearchType.SCAN).setScroll(
                    new TimeValue(60000)).setQuery(qb).setSize(100).execute().actionGet();

            while (true) {
                scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(600000)).execute().actionGet();
                for (SearchHit hit : scrollResp.getHits()) {
                    Map<String, Object> source = hit.getSource();
                    if (!source.isEmpty()) {
                        for (Iterator<Map.Entry<String, Object>> it = source.entrySet().iterator(); it.hasNext();) {
                            Map.Entry<String, Object> entry = it.next();
                            System.out.println(entry.getKey() + "=======" + entry.getValue());

                        }
                    }

                }
                if (scrollResp.hits().hits().length == 0) {
                    break;
                }

            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            client.close();
        }

    }
}

将paoding加入es中的代码主要在定义索引字段属性时,代码如下所示:

                // 定义索引字段属性
                XContentBuilder mapping = XContentFactory.jsonBuilder().startObject();
                mapping = mapping.startObject("title")
                                // 创建索引时使用paoding解析
                                .field("indexAnalyzer", "paoding")
                                // 搜索时使用paoding解析
                                .field("searchAnalyzer", "paoding")
                                .field("store", "yes")
                          .endObject();
                mapping = mapping.endObject();

5. 当你想为多个字段(例如一个实体的多个属性)建立索引并使用字段搜索时,代码如下所示:

import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.indices.IndexAlreadyExistsException;
import org.elasticsearch.node.Node;
import org.elasticsearch.node.NodeBuilder;
import org.elasticsearch.search.SearchHit;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * <p>
 * MyTest.java
 * </p>
 * <p>
 * </p>
 * 
 * @author $Author: Geloin $
 * @version $Revision: V5.1 $
 */
public class MyTest {

    private static Node node;

    @BeforeClass
    public static void beforeClass() {
        node = NodeBuilder.nodeBuilder().node();
    }

    /**
     * 
     * <p>
     * 创建索引
     * </p>
     * @author Geloin
     * Created [2012-12-29 下午5:38:22]
     * @throws Exception
     */
    @Test
    public void createIndex() throws Exception {

        Client client = node.client();
        try {

            try {
                // 预定义一个索引
                client.admin().indices().prepareCreate("app").execute().actionGet();
                
                // 定义索引字段属性
                XContentBuilder mapping = XContentFactory.jsonBuilder().startObject();
                mapping = mapping.startObject("article");
                mapping = mapping.startObject("id")
                                // 创建索引时使用paoding解析
                                .field("indexAnalyzer", "paoding")
                                // 搜索时使用paoding解析
                                .field("searchAnalyzer", "paoding")
                                .field("store", "yes")
                          .endObject();
                mapping = mapping.startObject("title")
                        // 创建索引时使用paoding解析
                        .field("indexAnalyzer", "paoding")
                        // 搜索时使用paoding解析
                        .field("searchAnalyzer", "paoding")
                        .field("store", "yes")
                        .endObject();
                mapping = mapping.startObject("createTime")
                        // 创建索引时使用paoding解析
                        .field("indexAnalyzer", "paoding")
                        // 搜索时使用paoding解析
                        .field("searchAnalyzer", "paoding")
                        .field("store", "yes")
                        .endObject();
                mapping = mapping.endObject();
                mapping = mapping.endObject();
                // type的值必须与第一个startObject("...")内的值相同,且必须有一个根目录,如article为根目录,id、title和createTime为子目录
                PutMappingRequest mappingRequest = Requests.putMappingRequest("app").type("article").source(mapping);
                client.admin().indices().putMapping(mappingRequest).actionGet();
            }
            catch (IndexAlreadyExistsException e) {
                System.out.println("索引库已存在");
            }

            String id = UUID.randomUUID().toString();
            // 生成文档
            XContentBuilder doc = XContentFactory.jsonBuilder().startObject();
            doc = doc.startObject("article");
            doc = doc.field("id", id);
            doc = doc.field("title", "java附魔大师");
            doc = doc.field("createTime", new Date());
            doc = doc.endObject();
            doc = doc.endObject();

            // 创建索引
            IndexResponse response = client.prepareIndex("app", "article", id).setSource(doc).execute().actionGet();

            System.out.println(response.getId() + "====" + response.getIndex() + "====" + response.getType());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            client.close();
        }
    }

    /**
     * 
     * <p>
     * 查询
     * </p>
     * @author Geloin
     * Created [2012-12-29 下午5:40:55]
     */
    @Test
    public void search() throws Exception {
        Client client = node.client();
        try {
//            QueryBuilder qb = QueryBuilders.fieldQuery("title", "大师");
            QueryBuilder qb = QueryBuilders.fieldQuery("article.title", "大师");
            SearchResponse scrollResp = client.prepareSearch("app").setSearchType(SearchType.SCAN).setScroll(
                    new TimeValue(60000)).setQuery(qb).setSize(100).execute().actionGet();

            while (true) {
                scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(600000)).execute().actionGet();
                for (SearchHit hit : scrollResp.getHits()) {
                    Map<String, Object> source = hit.getSource();
                    if (!source.isEmpty()) {
                        for (Iterator<Map.Entry<String, Object>> it = source.entrySet().iterator(); it.hasNext();) {
                            Map.Entry<String, Object> entry = it.next();
                            System.out.println(entry.getKey() + "=======" + entry.getValue());

                        }
                    }

                }
                if (scrollResp.hits().hits().length == 0) {
                    break;
                }

            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            client.close();
        }

    }
}

在这种情况下,使用title和article.title查询的结果一致,当然,如果除了article.title,还有member.title,那么结果就不一样了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值