【问题标题】:Configuring analyzer in elastic search在弹性搜索中配置分析器
【发布时间】:2015-01-22 14:45:41
【问题描述】:

我编写了下面的程序来了解如何使用弹性搜索进行全文搜索。在这里,当我搜索单个单词时,它可以正常工作,但我想搜索单词组合,但这不起作用。

package in.blogspot.randomcompiler.elastic_search_demo;

import in.blogspot.randomcompiler.elastic_search_impl.Event;

import java.util.Date;

import org.elasticsearch.action.count.CountRequestBuilder;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.FilterBuilder;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;

import com.fasterxml.jackson.core.JsonProcessingException;

public class ElasticSearchDemo
{
    public static void main( String[] args ) throws JsonProcessingException
    {
        Client client = new TransportClient()
        .addTransportAddress(new InetSocketTransportAddress("localhost", 9301));

        DeleteResponse deleteResponse1 = client.prepareDelete("chat-data", "event", "1").execute().actionGet();
        DeleteResponse deleteResponse2 = client.prepareDelete("chat-data", "event", "2").execute().actionGet();
        DeleteResponse deleteResponse3 = client.prepareDelete("chat-data", "event", "3").execute().actionGet();

        Event e1 = new Event("LOGIN", new Date(), "Agent1 logged into chat");
        String e1Json = e1.prepareJson();        
        System.out.println("JSON: " + e1Json);        
        IndexResponse indexResponse1 = client.prepareIndex("chat-data", "event", "1").setSource(e1Json).execute().actionGet();
        printIndexResponse("e1", indexResponse1);

        Event e2 = new Event("LOGOUT", new Date(), "Agent1 logged out of chat");
        String e2Json = e2.prepareJson();        
        System.out.println("JSON: " + e2Json);        
        IndexResponse indexResponse2 = client.prepareIndex("chat-data", "event", "2").setSource(e2Json).execute().actionGet();
        printIndexResponse("e2", indexResponse2);

        Event e3 = new Event("BREAK", new Date(), "Agent1 went on break in the middle of a chat");
        String e3Json = e3.prepareJson();        
        System.out.println("JSON: " + e3Json);        
        IndexResponse indexResponse3 = client.prepareIndex("chat-data", "event", "3").setSource(e3Json).execute().actionGet();
        printIndexResponse("e3", indexResponse3);

        FilterBuilder filterBuilder = FilterBuilders.termFilter("value", "break middle");

        SearchRequestBuilder searchBuilder = client.prepareSearch();
        searchBuilder.setPostFilter(filterBuilder);

        CountRequestBuilder countBuilder = client.prepareCount();
        countBuilder.setQuery(QueryBuilders.constantScoreQuery(filterBuilder));

        CountResponse countResponse1 = countBuilder.execute().actionGet();
        System.out.println("HITS: " + countResponse1.getCount());


        SearchResponse searchResponse1 = searchBuilder.execute().actionGet();
        SearchHits hits = searchResponse1.getHits();
        for(int i=0; i<hits.hits().length; i++) {
            SearchHit hit = hits.getAt(i);
            System.out.println("[" + i + "] " + hit.getId() + " : " +hit.sourceAsString());
        }

        client.close();
    }

    private static void printIndexResponse(String description, IndexResponse response) {
        System.out.println("Index response for: " + description);
        System.out.println("Index name: " + response.getIndex());
        System.out.println("Index type: " + response.getType());
        System.out.println("Index id: " + response.getId());
        System.out.println("Index version: " + response.getVersion());
    }
}

我面临的问题是,当我搜索“break middle”时它什么也不返回,期望它应该返回第三个事件。

我知道我需要配置一个不同的分析器而不是默认的分析器以使其正确索引。

有人可以帮助我了解如何做到这一点。有一些完整的例子就太好了。

【问题讨论】:

    标签: java elasticsearch lucene


    【解决方案1】:

    问题是因为你使用了Term过滤器造成的:

    FilterBuilder filterBuilder = FilterBuilders.termFilter("value", "break middle");
    

    术语过滤器不分析查询字符串中的数据 - 因此 Elasticsearch 正在寻找确切的字符串“break middle”。

    但是,ES 可能会将第三个文档分解为单独的术语,如下所示:

    Agent1 
    went 
    on 
    break 
    in 
    the 
    middle 
    of 
    a 
    chat
    

    要解决此问题,请使用过滤器或查询来分析您传递的字符串 - 例如使用 Query_String 查询或 Match 查询。

    例如:

    QueryBuilder qb = QueryBuilders.matchQuery("event", "break middle");
    

    或:

    QueryBuilder qb = QueryBuilders.queryString("break middle");
    

    请参阅Java API documentation for Elasticsearch 了解更多信息。

    【讨论】:

    • 如何将查询字符串或匹配项放入 java 调用中?
    • 非常感谢! QueryBuilder 工作起来轻而易举:)
    • 当然奥利!我还有几个疑问 1) 当我创建索引并立即搜索它时,我不会间歇性地返回结果。但是,作为回应,它说创建了索引。弹性搜索是否需要一些时间才能使索引可搜索? 2) 在索引文档时,我没有达到使用映射的目的。因为我能够使用默认映射和 QueryBuilder 查询全文。那么我什么时候以及为什么需要映射呢?
    • QueryBuilder queryBuilder = QueryBuilders.matchQuery("value", "middle going"); 输出:Jan 22, 2015 11:50:35 PM org.elasticsearch.plugins.PluginsService &lt;init&gt; INFO: [Living Diamond] loaded [], sites [] JSON: ... Index response for: e1 ... Index id: 1 ... JSON: ... Index response for: e2 ... Index id: 2 ... JSON: ... Index response for: e3 ... Index id: 3 ... HITS: 1 [0] 3 : {"type":"BREAK","date":1421950810187,"value":"Agent1 went on break in the middle of a chat"} 有时 HITS:0。
    • 你能把这个作为一个新问题发布吗?这样你会得到更多更好的答案。对于您的第二个问题 - 映射是自动生成的。这可能会满足您的所有要求,但可能不会 - 例如您需要一个自定义解析器来分析您的数据,您可能需要调整性能或在数据中设置“生存时间”。
    猜你喜欢
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 2021-02-03
    相关资源
    最近更新 更多