java - hibernate 搜索 : configure Facet for custom FieldBridge

标签 java lucene hibernate-search facet

在此示例中DateSplitBridge.java动态字段被添加到索引文档中:

public class DateSplitBridge implements FieldBridge {
...
   public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
...
      luceneOptions.addFieldToDocument( name + ".year", String.valueOf( year ), document);
...

如何为此类临时字段配置 Facet? 可以在 FieldBridge 本身中完成吗?

最佳答案

https://hibernate.atlassian.net/browse/HSEARCH-1686?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel&showAll=true 中找到解决方案

这里采用的版本:companyId是实体成员(长整型),isFavorite也是成员( boolean 型)。结果:在索引文档中,存在如下字段:customFieldFacet_1234,其值为:“true”或“false”。注意:没有@Facet注释

用法:

@Field(analyze = Analyze.NO, store = Store.YES, bridge = @FieldBridge(impl = CustomFieldBridge.class))
@Transient
public CustomField getFacetingCustomField() {
    return new CustomField("customFieldFacet_" + companyId, isFavorite);
}

场桥:

import org.apache.lucene.document.Document;
import org.apache.lucene.facet.sortedset.SortedSetDocValuesFacetField;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;

import java.io.IOException;

public class CustomFieldBridge implements FieldBridge {

    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
        if (value != null) {
            CustomField customField = (CustomField) value;
            if (customField.getFieldValue() != null) {
                String fieldName = customField.getFieldName();
                String fieldValue = customField.getFieldValue();
                CustomFacetsConfig config = new CustomFacetsConfig();
                config.setIndexFieldName(fieldName, fieldName);
                Document doc = new Document();
                doc.add(new SortedSetDocValuesFacetField(fieldName, fieldValue));
                try {
                    config.CustomBuild(doc, document);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

自定义Facet配置:

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.SortedSetDocValuesField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.facet.FacetsConfig;
import org.apache.lucene.facet.sortedset.SortedSetDocValuesFacetField;
import org.apache.lucene.facet.taxonomy.FacetLabel;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.util.BytesRef;

import java.io.IOException;
import java.util.*;

public class CustomFacetsConfig extends FacetsConfig {

    public Document CustomBuild(Document doc, Document destDocument) throws IOException {
        Map<String, List<SortedSetDocValuesFacetField>> dvByField = new HashMap<>();
        Set<String> seenDims = new HashSet<>();
        for (IndexableField field : doc.getFields()) {
            if (field.fieldType() == SortedSetDocValuesFacetField.TYPE) {
                SortedSetDocValuesFacetField facetField = (SortedSetDocValuesFacetField) field;
                FacetsConfig.DimConfig dimConfig = getDimConfig(facetField.dim);
                if (dimConfig.multiValued == false) {
                    checkSeen(seenDims, facetField.dim);
                }
                String indexFieldName = dimConfig.indexFieldName;
                List<SortedSetDocValuesFacetField> fields = dvByField.get(indexFieldName);
                if (fields == null) {
                    fields = new ArrayList<>();
                    dvByField.put(indexFieldName, fields);
                }
                fields.add(facetField);
            }
        }
        processSSDVFacetFields(dvByField, destDocument);
        return destDocument;
    }

    private void checkSeen(Set<String> seenDims, String dim) {
        if (seenDims.contains(dim)) {
            throw new IllegalArgumentException("dimension " + dim + " is not multiValued, but it appears more than once in this document");
        }
        seenDims.add(dim);
    }

    private void processSSDVFacetFields(Map<String, List<SortedSetDocValuesFacetField>> byField, Document doc) throws IOException {
        for (Map.Entry<String, List<SortedSetDocValuesFacetField>> ent : byField.entrySet()) {
            String indexFieldName = ent.getKey();
            for (SortedSetDocValuesFacetField facetField : ent.getValue()) {
                FacetLabel cp = new FacetLabel(facetField.dim, facetField.label);
                String fullPath = pathToString(cp.components, cp.length);
                doc.add(new SortedSetDocValuesField(indexFieldName, new BytesRef(fullPath)));
                doc.add(new StringField(indexFieldName, fullPath, Field.Store.YES));
            }
        }
    }

}

关于java - hibernate 搜索 : configure Facet for custom FieldBridge,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39574478/

相关文章:

java - 如何在java中只加载一次属性?

java - Java 和 MySQL 中多个 boolean 标志与多路复用整数(位)的效率

apache - 在SOLR中的片段前后显示省略号

java - 错误: Could not find or load main class

java - 如何使用 Hibernate Lucene 搜索对挪威语字符(Æ、Ø 和 Å)进行不区分大小写的排序?

java - 在一个方法中处理多个异常

java - 使用 solr 搜索进行高级搜索

java - 如何使用 apache lucene 索引优化搜索

java - hibernate 搜索索引不起作用

java - 由于 SearchFactoryIntegrator 不在注册表中,无法在 JBoss 7 上查询 Infinispan