private void ProcessFacetFields(ITaxonomyWriter taxoWriter, IDictionary <string, IList <FacetField> > byField, Document doc) { foreach (KeyValuePair <string, IList <FacetField> > ent in byField) { string indexFieldName = ent.Key; //System.out.println(" indexFieldName=" + indexFieldName + " fields=" + ent.getValue()); Int32sRef ordinals = new Int32sRef(32); foreach (FacetField facetField in ent.Value) { FacetsConfig.DimConfig ft = GetDimConfig(facetField.Dim); if (facetField.Path.Length > 1 && ft.IsHierarchical == false) { throw new ArgumentException("dimension \"" + facetField.Dim + "\" is not hierarchical yet has " + facetField.Path.Length + " components"); } FacetLabel cp = new FacetLabel(facetField.Dim, facetField.Path); CheckTaxoWriter(taxoWriter); int ordinal = taxoWriter.AddCategory(cp); if (ordinals.Length == ordinals.Int32s.Length) { ordinals.Grow(ordinals.Length + 1); } ordinals.Int32s[ordinals.Length++] = ordinal; //System.out.println("ords[" + (ordinals.length-1) + "]=" + ordinal); //System.out.println(" add cp=" + cp); if (ft.IsMultiValued && (ft.IsHierarchical || ft.RequireDimCount)) { //System.out.println(" add parents"); // Add all parents too: int parent = taxoWriter.GetParent(ordinal); while (parent > 0) { if (ordinals.Int32s.Length == ordinals.Length) { ordinals.Grow(ordinals.Length + 1); } ordinals.Int32s[ordinals.Length++] = parent; parent = taxoWriter.GetParent(parent); } if (ft.RequireDimCount == false) { // Remove last (dimension) ord: ordinals.Length--; } } // Drill down: for (int i = 1; i <= cp.Length; i++) { doc.Add(new StringField(indexFieldName, PathToString(cp.Components, i), Field.Store.NO)); } } // Facet counts: // DocValues are considered stored fields: doc.Add(new BinaryDocValuesField(indexFieldName, DedupAndEncode(ordinals))); } }
/// <summary> /// Translates any added <see cref="FacetField"/>s into normal fields for indexing. /// /// <para> /// <b>NOTE:</b> you should add the returned document to <see cref="Index.IndexWriter"/>, not the /// input one! /// </para> /// </summary> public virtual Document Build(ITaxonomyWriter taxoWriter, Document doc) { // Find all FacetFields, collated by the actual field: IDictionary <string, IList <FacetField> > byField = new Dictionary <string, IList <FacetField> >(); // ... and also all SortedSetDocValuesFacetFields: IDictionary <string, IList <SortedSetDocValuesFacetField> > dvByField = new Dictionary <string, IList <SortedSetDocValuesFacetField> >(); // ... and also all AssociationFacetFields IDictionary <string, IList <AssociationFacetField> > assocByField = new Dictionary <string, IList <AssociationFacetField> >(); var seenDims = new JCG.HashSet <string>(); foreach (IIndexableField field in doc.Fields) { if (field.IndexableFieldType == FacetField.TYPE) { FacetField facetField = (FacetField)field; FacetsConfig.DimConfig dimConfig = GetDimConfig(facetField.Dim); if (dimConfig.IsMultiValued == false) { CheckSeen(seenDims, facetField.Dim); } string indexFieldName = dimConfig.IndexFieldName; if (!byField.TryGetValue(indexFieldName, out IList <FacetField> fields)) { fields = new List <FacetField>(); byField[indexFieldName] = fields; } fields.Add(facetField); } if (field.IndexableFieldType == SortedSetDocValuesFacetField.TYPE) { var facetField = (SortedSetDocValuesFacetField)field; FacetsConfig.DimConfig dimConfig = GetDimConfig(facetField.Dim); if (dimConfig.IsMultiValued == false) { CheckSeen(seenDims, facetField.Dim); } string indexFieldName = dimConfig.IndexFieldName; if (!dvByField.TryGetValue(indexFieldName, out IList <SortedSetDocValuesFacetField> fields)) { fields = new List <SortedSetDocValuesFacetField>(); dvByField[indexFieldName] = fields; } fields.Add(facetField); } if (field.IndexableFieldType == AssociationFacetField.TYPE) { AssociationFacetField facetField = (AssociationFacetField)field; FacetsConfig.DimConfig dimConfig = GetDimConfig(facetField.Dim); if (dimConfig.IsMultiValued == false) { CheckSeen(seenDims, facetField.Dim); } if (dimConfig.IsHierarchical) { throw new ArgumentException("AssociationFacetField cannot be hierarchical (dim=\"" + facetField.Dim + "\")"); } if (dimConfig.RequireDimCount) { throw new ArgumentException("AssociationFacetField cannot requireDimCount (dim=\"" + facetField.Dim + "\")"); } string indexFieldName = dimConfig.IndexFieldName; if (!assocByField.TryGetValue(indexFieldName, out IList <AssociationFacetField> fields)) { fields = new List <AssociationFacetField>(); assocByField[indexFieldName] = fields; } fields.Add(facetField); // Best effort: detect mis-matched types in same // indexed field: string type; if (facetField is Int32AssociationFacetField) { type = "int"; } else if (facetField is SingleAssociationFacetField) { type = "float"; } else { type = "bytes"; } // NOTE: not thread safe, but this is just best effort: if (!assocDimTypes.TryGetValue(indexFieldName, out string curType)) { assocDimTypes[indexFieldName] = type; } else if (!curType.Equals(type, StringComparison.Ordinal)) { throw new ArgumentException("mixing incompatible types of AssocationFacetField (" + curType + " and " + type + ") in indexed field \"" + indexFieldName + "\"; use FacetsConfig to change the indexFieldName for each dimension"); } } } Document result = new Document(); ProcessFacetFields(taxoWriter, byField, result); ProcessSSDVFacetFields(dvByField, result); ProcessAssocFacetFields(taxoWriter, assocByField, result); //System.out.println("add stored: " + addedStoredFields); foreach (IIndexableField field in doc.Fields) { IIndexableFieldType ft = field.IndexableFieldType; if (ft != FacetField.TYPE && ft != SortedSetDocValuesFacetField.TYPE && ft != AssociationFacetField.TYPE) { result.Add(field); } } return(result); }