blob: 35b03548a52e7ae858614b5f50985acd86d34eb4 [file] [log] [blame]
diff --git a/lucene/core/src/java/org/apache/lucene/document/FieldType.java b/lucene/core/src/java/org/apache/lucene/document/FieldType.java
index a21572e96c..cdf01e1626 100644
--- a/lucene/core/src/java/org/apache/lucene/document/FieldType.java
+++ b/lucene/core/src/java/org/apache/lucene/document/FieldType.java
@@ -17,6 +17,9 @@
package org.apache.lucene.document;
+import java.util.HashMap;
+import java.util.Map;
+
import org.apache.lucene.analysis.Analyzer; // javadocs
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.IndexOptions;
@@ -41,6 +44,7 @@ public class FieldType implements IndexableFieldType {
private int dataDimensionCount;
private int indexDimensionCount;
private int dimensionNumBytes;
+ private Map<String, String> attributes = null;
/**
* Create a new mutable FieldType with all of the properties from <code>ref</code>
@@ -58,6 +62,7 @@ public class FieldType implements IndexableFieldType {
this.dataDimensionCount = ref.pointDataDimensionCount();
this.indexDimensionCount = ref.pointIndexDimensionCount();
this.dimensionNumBytes = ref.pointNumBytes();
+ this.attributes = ref.getAttributes();
// Do not copy frozen!
}
@@ -341,6 +346,30 @@ public class FieldType implements IndexableFieldType {
return dimensionNumBytes;
}
+ /**
+ * Puts an attribute value.
+ * <p>
+ * This is a key-value mapping for the field that the codec can use
+ * to store additional metadata.
+ * <p>
+ * If a value already exists for the field, it will be replaced with
+ * the new value. This method is not thread-safe, user must not add attributes
+ * while other threads are indexing documents with this field type.
+ *
+ * @lucene.experimental
+ */
+ public String putAttribute(String key, String value) {
+ if (attributes == null) {
+ attributes = new HashMap<>();
+ }
+ return attributes.put(key, value);
+ }
+
+ @Override
+ public Map<String, String> getAttributes() {
+ return attributes;
+ }
+
/** Prints a Field for human consumption. */
@Override
public String toString() {
diff --git a/lucene/core/src/java/org/apache/lucene/index/DefaultIndexingChain.java b/lucene/core/src/java/org/apache/lucene/index/DefaultIndexingChain.java
index 4cc981dbd7..91a69cf2f1 100644
--- a/lucene/core/src/java/org/apache/lucene/index/DefaultIndexingChain.java
+++ b/lucene/core/src/java/org/apache/lucene/index/DefaultIndexingChain.java
@@ -661,6 +661,10 @@ final class DefaultIndexingChain extends DocConsumer {
FieldInfo fi = fieldInfos.getOrAdd(name);
initIndexOptions(fi, fieldType.indexOptions());
+ if (fieldType.getAttributes() != null) {
+ fieldType.getAttributes().forEach((k, v) -> fi.putAttribute(k, v));
+ }
+
fp = new PerField(docWriter.getIndexCreatedVersionMajor(), fi, invert);
fp.next = fieldHash[hashPos];
fieldHash[hashPos] = fp;
diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexableFieldType.java b/lucene/core/src/java/org/apache/lucene/index/IndexableFieldType.java
index b2b2e773ca..59c5ab5192 100644
--- a/lucene/core/src/java/org/apache/lucene/index/IndexableFieldType.java
+++ b/lucene/core/src/java/org/apache/lucene/index/IndexableFieldType.java
@@ -17,6 +17,8 @@
package org.apache.lucene.index;
+import java.util.Map;
+
import org.apache.lucene.analysis.Analyzer; // javadocs
/**
@@ -111,4 +113,14 @@ public interface IndexableFieldType {
* The number of bytes in each dimension's values.
*/
public int pointNumBytes();
+
+ /**
+ * Attributes for the field type.
+ *
+ * Attributes are not thread-safe, user must not add attributes while other threads are indexing documents
+ * with this field type.
+ *
+ * @return Map
+ */
+ public Map<String, String> getAttributes();
}
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestFieldInfos.java b/lucene/core/src/test/org/apache/lucene/index/TestFieldInfos.java
index 3fe5fa9d2c..79fb5abae7 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestFieldInfos.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestFieldInfos.java
@@ -23,6 +23,7 @@ import java.util.Iterator;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.StringField;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.LuceneTestCase;
@@ -93,6 +94,32 @@ public class TestFieldInfos extends LuceneTestCase {
dir.close();
}
+ public void testFieldAttributes() throws Exception{
+ Directory dir = newDirectory();
+ IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random()))
+ .setMergePolicy(NoMergePolicy.INSTANCE));
+
+ Document d = new Document();
+ FieldType type = new FieldType();
+ type.setStored(true);
+ type.putAttribute("testKey", "testValue");
+ d.add(new Field("f", "v", type));
+ writer.addDocument(d);
+ writer.commit();
+ writer.close();
+
+ SegmentInfos sis = SegmentInfos.readLatestCommit(dir);
+ FieldInfos fis = IndexWriter.readFieldInfos(sis.info(0));
+ Iterator<FieldInfo> it = fis.iterator();
+ while(it.hasNext()) {
+ FieldInfo fi = it.next();
+ assertEquals(0, fi.number);
+ assertEquals("f", fi.name);
+ assertEquals("testValue", fi.getAttribute("testKey"));
+ }
+ dir.close();
+ }
+
public void testMergedFieldInfos_empty() throws IOException {
Directory dir = newDirectory();
IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random())));
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexableField.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexableField.java
index 1091b2485e..59dbae3cd7 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestIndexableField.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexableField.java
@@ -21,6 +21,7 @@ import java.io.Reader;
import java.io.StringReader;
import java.util.Collections;
import java.util.Iterator;
+import java.util.Map;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
@@ -104,6 +105,11 @@ public class TestIndexableField extends LuceneTestCase {
public int pointNumBytes() {
return 0;
}
+
+ @Override
+ public Map<String, String> getAttributes() {
+ return null;
+ }
};
public MyField(int counter) {
diff --git a/solr/core/src/java/org/apache/solr/schema/SchemaField.java b/solr/core/src/java/org/apache/solr/schema/SchemaField.java
index 7d9449e6d9..100a963c1c 100644
--- a/solr/core/src/java/org/apache/solr/schema/SchemaField.java
+++ b/solr/core/src/java/org/apache/solr/schema/SchemaField.java
@@ -430,4 +430,9 @@ public final class SchemaField extends FieldProperties implements IndexableField
public int pointNumBytes() {
return 0;
}
+
+ @Override
+ public Map<String, String> getAttributes() {
+ return null;
+ }
}