2016-09-19 5 views
1
이 예에서

에 대한 패싯을 구성 DateSplitBridge.java 동적 필드는 인덱스 문서에 추가됩니다최대 절전 모드 검색 : 사용자 정의 FieldBridge

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

가 어떻게 같은 임시 필드 패싯을 구성합니까? FieldBridge 자체에서 수행 할 수 있습니까? 회사 ID 엔티티 부재 (긴) isFavorite 또한 부재 (부울)이다

답변

0

용액 여기

https://hibernate.atlassian.net/browse/HSEARCH-1686?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel&showAll=true에서 발견 된 버전을 채용. 결과 : 인덱싱 된 문서에는 customFieldFacet_1234 값이 "true"또는 "false"와 같은 필드가 있습니다. 참고 :

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

FieldBridge :

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(); 
       } 
      } 
     } 
    } 
} 

CustomFacetConfig :

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)); 
      } 
     } 
    } 

} 
0

내가 사용 해봤 같은 CustomFacetConfig가 적용

가 사용에는 @Facet 주석이없는 비슷한 사용자 정의 캘린더 분할,하지만 난 여전히 오류 :

public class CalendarSplitBridge implements FieldBridge { 

    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) { 
     Calendar cal = (Calendar) value; 
     int iyear = cal.get(Calendar.YEAR); 
     int imonth = cal.get(Calendar.MONTH) + 1; 
     int iday = cal.get(Calendar.DAY_OF_MONTH); 

     String year = String.valueOf(iyear); 
     String month = (imonth < 10 ? "0" : "") + String.valueOf(imonth); 
     String day = (iday < 10 ? "0" : "") + String.valueOf(iday); 

     addField(name + ".year", year, document); 
     addField(name + ".month", month, document); 
     addField(name + ".day", day, document); 
     addField(name + ".yyyymmdd", year+month+day, document); 
    } 

    private void addField(final String fieldName, final String fieldValue, final Document document) { 
     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(); 
     } 
    } 
} 

그리고 내 매핑을

을 : 당신이 당신의 솔루션이 DateSplitBridge에

asm.property("creationDate", ElementType.METHOD) 
     .bridge(CalendarSplitBridge.class) 
      .field() 
       .name("creationDate.year") 
       .analyze(Analyze.NO) 
       .store(Store.YES) 
       .facet() 
        .name("creationDate.year") 
      .field() 
       .name("creationDate.month") 
       .analyze(Analyze.NO) 
       .store(Store.YES) 
       .facet() 
        .name("creationDate.month") 
      .field() 
       .name("creationDate.day") 
       .analyze(Analyze.NO) 
       .store(Store.YES) 
       .facet() 
        .name("creationDate.day"); 

를 적용 공유 할 수 있습니다 다음과 같이

Facet request 'creationDate.year' tries to facet on field 'creationDate.year' which either does not exist or is not configured for faceting (via @Facet)

내 사용자 정의 브리지 구현은?

+1

프로그래밍 API로 수행 한 작업이 의도 한 작업과 다를 수 있습니다. .bridge() 호출은 모든 필드에 대한 기본 브리지 만 설정합니다. 그래서 당신의 다리는'creationDate.year.year' 필드,'creationDate.year.month' 필드,'creationDate.year.day' 필드,'creationDate.month.year' 필드 등을 채우게 될 것입니다. 'creationDate.year' 필드는 색인에서 비어 있습니다. 이전 버전의 검색에서는이 오류가 발생할 수 있습니다. –