Skip to content

Commit b8f9ac6

Browse files
committed
Pull the flattened field type into a mapper plugin.
1 parent c995f68 commit b8f9ac6

File tree

43 files changed

+1012
-797
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1012
-797
lines changed

modules/flattened/build.gradle

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
esplugin {
21+
description 'Flattened object fields'
22+
classname 'org.elasticsearch.plugin.mapper.FlattenedMapperPlugin'
23+
}
24+
25+
integTestRunner {
26+
27+
}

server/src/main/java/org/elasticsearch/index/mapper/FlatObjectFieldMapper.java renamed to modules/flattened/src/main/java/org/elasticsearch/index/mapper/FlatObjectFieldMapper.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public Builder splitQueriesOnWhitespace(boolean splitQueriesOnWhitespace) {
160160
}
161161

162162
@Override
163-
public Builder addMultiField(Mapper.Builder mapperBuilder) {
163+
public Builder addMultiField(Mapper.Builder<?, ?> mapperBuilder) {
164164
throw new UnsupportedOperationException("[fields] is not supported for [" + CONTENT_TYPE + "] fields.");
165165
}
166166

@@ -189,7 +189,7 @@ public FlatObjectFieldMapper build(BuilderContext context) {
189189
public static class TypeParser implements Mapper.TypeParser {
190190
@Override
191191
public Mapper.Builder<?,?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
192-
FlatObjectFieldMapper.Builder builder = new FlatObjectFieldMapper.Builder(name);
192+
Builder builder = new Builder(name);
193193
parseField(builder, name, node, parserContext);
194194
for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext();) {
195195
Map.Entry<String, Object> entry = iterator.next();
@@ -424,6 +424,11 @@ public OrdinalMap getOrdinalMap() {
424424
+ delegate.getFieldName() + "] does not allow access to the underlying ordinal map.");
425425
}
426426

427+
@Override
428+
public boolean supportsGlobalOrdinalsMapping() {
429+
return false;
430+
}
431+
427432
@Override
428433
public Index index() {
429434
return delegate.index();
@@ -559,11 +564,17 @@ protected FlatObjectFieldMapper clone() {
559564
return (FlatObjectFieldMapper) super.clone();
560565
}
561566

567+
@Override
568+
public boolean supportsKeyedLookup() {
569+
return true;
570+
}
571+
562572
@Override
563573
public RootFlatObjectFieldType fieldType() {
564574
return (RootFlatObjectFieldType) super.fieldType();
565575
}
566576

577+
@Override
567578
public KeyedFlatObjectFieldType keyedFieldType(String key) {
568579
return new KeyedFlatObjectFieldType(keyedFieldName(), key, fieldType());
569580
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.plugin.mapper;
21+
22+
import org.elasticsearch.index.mapper.FlatObjectFieldMapper;
23+
import org.elasticsearch.index.mapper.Mapper;
24+
import org.elasticsearch.plugins.MapperPlugin;
25+
import org.elasticsearch.plugins.Plugin;
26+
import org.elasticsearch.plugins.SearchPlugin;
27+
28+
import java.util.Map;
29+
30+
import static java.util.Collections.singletonMap;
31+
32+
public class FlattenedMapperPlugin extends Plugin implements MapperPlugin, SearchPlugin {
33+
34+
@Override
35+
public Map<String, Mapper.TypeParser> getMappers() {
36+
return singletonMap(FlatObjectFieldMapper.CONTENT_TYPE, new FlatObjectFieldMapper.TypeParser());
37+
}
38+
39+
}

server/src/test/java/org/elasticsearch/index/mapper/FlatObjectFieldMapperTests.java renamed to modules/flattened/src/test/java/org/elasticsearch/index/mapper/FlatObjectFieldMapperTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.elasticsearch.index.IndexService;
3232
import org.elasticsearch.index.mapper.FlatObjectFieldMapper.KeyedFlatObjectFieldType;
3333
import org.elasticsearch.index.mapper.FlatObjectFieldMapper.RootFlatObjectFieldType;
34+
import org.elasticsearch.plugin.mapper.FlattenedMapperPlugin;
3435
import org.elasticsearch.plugins.Plugin;
3536
import org.elasticsearch.test.ESSingleNodeTestCase;
3637
import org.elasticsearch.test.InternalSettingsPlugin;
@@ -55,7 +56,7 @@ public void setup() {
5556

5657
@Override
5758
protected Collection<Class<? extends Plugin>> getPlugins() {
58-
return pluginList(InternalSettingsPlugin.class);
59+
return pluginList(FlattenedMapperPlugin.class, InternalSettingsPlugin.class);
5960
}
6061

6162
public void testDefaults() throws Exception {
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.mapper;
21+
22+
import org.apache.lucene.analysis.core.KeywordAnalyzer;
23+
import org.apache.lucene.document.Document;
24+
import org.apache.lucene.document.SortedSetDocValuesField;
25+
import org.apache.lucene.index.DirectoryReader;
26+
import org.apache.lucene.index.IndexWriter;
27+
import org.apache.lucene.index.IndexWriterConfig;
28+
import org.apache.lucene.store.Directory;
29+
import org.apache.lucene.util.Accountable;
30+
import org.apache.lucene.util.BytesRef;
31+
import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader;
32+
import org.elasticsearch.index.IndexService;
33+
import org.elasticsearch.index.fielddata.IndexFieldData;
34+
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
35+
import org.elasticsearch.index.fielddata.IndexFieldDataService;
36+
import org.elasticsearch.index.mapper.FlatObjectFieldMapper.KeyedFlatObjectFieldData;
37+
import org.elasticsearch.index.mapper.FlatObjectFieldMapper.KeyedFlatObjectFieldType;
38+
import org.elasticsearch.index.shard.ShardId;
39+
import org.elasticsearch.indices.IndicesService;
40+
import org.elasticsearch.plugin.mapper.FlattenedMapperPlugin;
41+
import org.elasticsearch.plugins.Plugin;
42+
import org.elasticsearch.test.ESSingleNodeTestCase;
43+
import org.elasticsearch.test.InternalSettingsPlugin;
44+
45+
import java.io.IOException;
46+
import java.util.Collection;
47+
import java.util.concurrent.atomic.AtomicInteger;
48+
49+
public class FlatObjectIndexFieldDataTests extends ESSingleNodeTestCase {
50+
51+
@Override
52+
protected Collection<Class<? extends Plugin>> getPlugins() {
53+
return pluginList(FlattenedMapperPlugin.class, InternalSettingsPlugin.class);
54+
}
55+
56+
public void testGlobalFieldDataCaching() throws IOException {
57+
// Set up the index service.
58+
IndexService indexService = createIndex("test");
59+
IndicesService indicesService = getInstanceFromNode(IndicesService.class);
60+
IndexFieldDataService ifdService = new IndexFieldDataService(indexService.getIndexSettings(),
61+
indicesService.getIndicesFieldDataCache(),
62+
indicesService.getCircuitBreakerService(),
63+
indexService.mapperService());
64+
65+
Mapper.BuilderContext ctx = new Mapper.BuilderContext(indexService.getIndexSettings().getSettings(), new ContentPath(1));
66+
FlatObjectFieldMapper fieldMapper = new FlatObjectFieldMapper.Builder("json").build(ctx);
67+
68+
AtomicInteger onCacheCalled = new AtomicInteger();
69+
ifdService.setListener(new IndexFieldDataCache.Listener() {
70+
@Override
71+
public void onCache(ShardId shardId, String fieldName, Accountable ramUsage) {
72+
assertEquals(fieldMapper.keyedFieldName(), fieldName);
73+
onCacheCalled.incrementAndGet();
74+
}
75+
});
76+
77+
// Add some documents.
78+
Directory directory = newDirectory();
79+
IndexWriterConfig config = new IndexWriterConfig(new KeywordAnalyzer());
80+
IndexWriter writer = new IndexWriter(directory, config);
81+
82+
Document doc = new Document();
83+
doc.add(new SortedSetDocValuesField("json._keyed", new BytesRef("some_key\0some_value")));
84+
writer.addDocument(doc);
85+
writer.commit();
86+
writer.addDocument(doc);
87+
DirectoryReader reader = ElasticsearchDirectoryReader.wrap(
88+
DirectoryReader.open(writer),
89+
new ShardId("test", "_na_", 1));
90+
91+
// Load global field data for subfield 'key'.
92+
KeyedFlatObjectFieldType fieldType1 = fieldMapper.keyedFieldType("key");
93+
IndexFieldData<?> ifd1 = ifdService.getForField(fieldType1);
94+
assertTrue(ifd1 instanceof KeyedFlatObjectFieldData);
95+
96+
KeyedFlatObjectFieldData fieldData1 = (KeyedFlatObjectFieldData) ifd1;
97+
assertEquals("key", fieldData1.getKey());
98+
fieldData1.loadGlobal(reader);
99+
assertEquals(1, onCacheCalled.get());
100+
101+
// Load global field data for the subfield 'other_key'.
102+
KeyedFlatObjectFieldType fieldType2 = fieldMapper.keyedFieldType("other_key");
103+
IndexFieldData<?> ifd2 = ifdService.getForField(fieldType2);
104+
assertTrue(ifd2 instanceof KeyedFlatObjectFieldData);
105+
106+
KeyedFlatObjectFieldData fieldData2 = (KeyedFlatObjectFieldData) ifd2;
107+
assertEquals("other_key", fieldData2.getKey());
108+
fieldData2.loadGlobal(reader);
109+
assertEquals(1, onCacheCalled.get());
110+
111+
ifdService.clear();
112+
reader.close();
113+
writer.close();
114+
directory.close();
115+
}
116+
}

0 commit comments

Comments
 (0)