簡體   English   中英

在 Hibernate 搜索 6 和 Elasticsearch 后端突出顯示

[英]Highlighting in Hibernate Search 6 and Elasticsearch backend

我們正在使用Elasticsearch后端將 java 應用程序從 Hibernate 搜索 5 轉換為 6。

有關一些好的背景信息,請參閱How to do highlighting within HibernateSearch over Elasticsearch以了解我們在將突出顯示代碼從 Lucene 升級到 Elasticsearch 后端時遇到的問題以及它是如何解決的。

Hibernate Search 6 seems to support using 2 backends at the same time, Lucene and Elasticsearch, so we'd like to use Elasticsearch for all our queries and Lucene for the highlighting, if that's possible.

這基本上是我們正在嘗試做的事情:

    public boolean matchPhoneNumbers() {
        String phoneNumber1 = "603-436-1234";
        String phoneNumber2 = "603-436-1234";

        LuceneBackend luceneBackend =
                Search.mapping(entityManager.getEntityManagerFactory())
                        .backend().unwrap(LuceneBackend.class);

        Analyzer analyzer = luceneBackend.analyzer("phoneNumberKeywordAnalyzer").get();

        //... builds a Lucene Query using the analyzer and phoneNumber1 term     
        Query phoneNumberQuery = buildQuery(analyzer, phoneNumber1, ...);

        return isMatch("phoneNumberField", phoneNumber2, phoneNumberQuery, analyzer);
    }

   private boolean isMatch(String field, String target, Query sourceQ, Analyzer analyzer) {
        Highlighter highlighter = new Highlighter(new QueryScorer(sourceQ, field));
        highlighter.setTextFragmenter(new NullFragmenter());

        try {
            String result = highlighter.getBestFragment(analyzer, field, target);
            return StringUtils.hasText(result);
        } catch (IOException e) {
            ...
        }
    }

到目前為止,我嘗試的是根據文檔在配置屬性中配置兩個單獨的后端,如下所示:

properties.setProperty("hibernate.search.backends.elasticsearch.analysis.configurer", "com.bt.demo.search.AnalysisConfigurer");
properties.setProperty("hibernate.search.backends.lucene.analysis.configurer", "com.bt.demo.search.CustomLuceneAnalysisConfigurer");
properties.setProperty("hibernate.search.backends.elasticsearch.type", "elasticsearch");
properties.setProperty("hibernate.search.backends.lucene.type", "lucene");
properties.setProperty("hibernate.search.backends.elasticsearch.uris", "http://127.0.0.1:9200");

AnalysisConfigurer class 實現 ElasticsearchAnalysisConfigurer 和 CustomLuceneAnalysisConfigurer 從 LuceneAnalysisConfigurer 實現。

分析器定義了兩次,一次在 Elasticsearch 配置器中,另一次在 Lucene 配置器中。

I don't know why both hibernate.search.backends.elasticsearch.type and hibernate.search.backends.lucene.type are necessary but if I don't include the lucene.type, I get Ambiguous backend type: configuration property 'hibernate.search.backends.lucene.type' is not set

但如果我確實設置了兩種后端屬性類型,我會得到HSEARCH000575: No default backend. Check that at least one entity is configured to target the default backend 在嘗試檢索 Lucene 后端時, HSEARCH000575: No default backend. Check that at least one entity is configured to target the default backend ,例如:

Search.mapping(entityManager.getEntityManagerFactory())
                        .backend().unwrap(LuceneBackend.class);

嘗試檢索 Elasticsearch 后端時出現相同的錯誤。

我還向我的實體添加了@Indexed(..., backend = "elasticsearch") ,因為我希望將它們保存到 Elasticsearch 並且在 Lucene 中不需要它們。 我還嘗試使用 @Indexed(..., backend = "lucene") 添加一個假實體,但沒有任何區別。

我配置錯了什么?

I don't know why both hibernate.search.backends.elasticsearch.type and hibernate.search.backends.lucene.type are necessary but if I don't include the lucene.type, I get Ambiguous backend type: configuration property 'hibernate .search.backends.lucene.type' 未設置。

那是因為后端名稱就是這樣:一個名稱。 Hibernate 搜索不會從中推斷出特定信息,即使您將后端命名為“lucene”或“elasticsearch”。 眾所周知,您可以擁有多個 Elasticsearch 后端:)

但如果我確實設置了兩種后端屬性類型,我會得到 HSEARCH000575: No default backend。 在嘗試檢索 Lucene 后端時,檢查是否至少將一個實體配置為以默認后端為目標,例如:

 Search.mapping(entityManager.getEntityManagerFactory()).backend().unwrap(LuceneBackend.class); ``

您撥打.backend() ,它檢索了默認后端,即沒有名稱的后端,並通過ZCB1F008EEBF5012C4EF9A2C36E2C36E574D61Z.SEARCHEND hibernate.search.backend.*而不是hibernate.search.backends.<somename>.* ://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#configuration-structure )。

但是您顯然將所有實體映射到一個命名后端,一個名為elasticsearch和一個名為lucene 所以默認后端不存在。

你應該這樣稱呼:

Search.mapping(entityManager.getEntityManagerFactory())
                        .backend("lucene").unwrap(LuceneBackend.class);

我還向我的實體添加了@Indexed(..., backend = "elasticsearch"),因為我希望將它們保存到 Elasticsearch

由於您顯然只想使用一個后端進行索引,因此我建議您恢復該更改(保留@Indexed而不設置@Indexed.backend )並簡單地使用默認后端。

簡而言之,刪除@Indexed.backend並替換它:

properties.setProperty("hibernate.search.backends.elasticsearch.analysis.configurer", "com.bt.demo.search.AnalysisConfigurer");
properties.setProperty("hibernate.search.backends.lucene.analysis.configurer", "com.bt.demo.search.CustomLuceneAnalysisConfigurer");
properties.setProperty("hibernate.search.backends.elasticsearch.type", "elasticsearch");
properties.setProperty("hibernate.search.backends.lucene.type", "lucene");
properties.setProperty("hibernate.search.backends.elasticsearch.uris", "http://127.0.0.1:9200");

有了這個

properties.setProperty("hibernate.search.backend.analysis.configurer", "com.bt.demo.search.AnalysisConfigurer");
properties.setProperty("hibernate.search.backends.lucene.analysis.configurer", "com.bt.demo.search.CustomLuceneAnalysisConfigurer");
properties.setProperty("hibernate.search.backend.type", "elasticsearch");
properties.setProperty("hibernate.search.backends.lucene.type", "lucene");
properties.setProperty("hibernate.search.backend.uris", "http://127.0.0.1:9200");

從技術上講,您不必這樣做,但我認為從長遠來看它會更簡單。 它將 Lucene 后端保留為單獨的 hack,不會影響您的整個應用程序。

我還嘗試使用 @Indexed(..., backend = "lucene") 添加一個假實體

我確認您需要將假實體映射到“lucene”后端,否則 Hibernate Search 將不會創建“lucene”后端。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM