Add a GetFieldMapping API
This new API allows to get the mapping for a specific set of fields rather than get the whole index mapping and traverse it. The fields to be retrieved can be specified by their full path, index name and field name and will be resolved in this order. In case multiple field match, the first one will be returned. Since we are now generating the output (rather then fall back to the stored mapping), you can specify `include_defaults`=true on the request to have default values returned. Closes #3941
This commit is contained in:
parent
f16eb7a243
commit
8819f91d47
|
@ -21,6 +21,8 @@ and warmers.
|
|||
== Mapping management:
|
||||
|
||||
* <<indices-put-mapping>>
|
||||
* <<indices-get-mapping>>
|
||||
* <<indices-get-field-mapping>>
|
||||
* <<indices-delete-mapping>>
|
||||
* <<indices-types-exists>>
|
||||
|
||||
|
@ -68,6 +70,8 @@ include::indices/put-mapping.asciidoc[]
|
|||
|
||||
include::indices/get-mapping.asciidoc[]
|
||||
|
||||
include::indices/get-field-mapping.asciidoc[]
|
||||
|
||||
include::indices/types-exists.asciidoc[]
|
||||
|
||||
include::indices/delete-mapping.asciidoc[]
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
[[indices-get-field-mapping]]
|
||||
== Get Field Mapping
|
||||
|
||||
The get field mapping API allows you to retrieve mapping definitions for one or more fields.
|
||||
This is useful when you do not need the complete type mapping returned by
|
||||
the <<indices-get-mapping>> API.
|
||||
|
||||
The following returns the mapping of the field `text` only:
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
curl -XGET 'http://localhost:9200/twitter/tweet/_mapping/field/text'
|
||||
--------------------------------------------------
|
||||
|
||||
For which the response is (assuming `text` is a default string field):
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"twitter": {
|
||||
"tweet": {
|
||||
"text": {
|
||||
"full_name": "text",
|
||||
"mapping": {
|
||||
"text": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
||||
|
||||
|
||||
[float]
|
||||
=== Multiple Indices, Types and Fields
|
||||
|
||||
The get field mapping API can be used to get the mapping of multiple fields from more than one index or type
|
||||
with a single call. General usage of the API follows the
|
||||
following syntax: `host:port/{index}/{type}/_mapping/field/{field}` where
|
||||
`{index}`, `{type}` and `{field}` can stand for comma-separated list of names. To
|
||||
get mappings for all indices you can use `_all` for `{index}`. The
|
||||
following are some examples:
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
curl -XGET 'http://localhost:9200/twitter,kimchy/_mapping/field/message'
|
||||
|
||||
curl -XGET 'http://localhost:9200/_all/tweet,book/_mapping/field/message,user.id'
|
||||
--------------------------------------------------
|
||||
|
||||
[float]
|
||||
=== Specifying fields
|
||||
|
||||
The get mapping api allows you to specify fields using any of the following:
|
||||
|
||||
[horizontal]
|
||||
Full names:: the full path, including any parent object name the field is
|
||||
part of (ex. `user.id`).
|
||||
Index names:: the name of the lucene field (can be different than the
|
||||
field name if the `index_name` option of the mapping is used).
|
||||
Field names:: the name of the field without the path to it (ex. `id` for `{ "user" : { "id" : 1 } }`).
|
||||
|
||||
The above options are specified in the order the `field` parameter is resolved.
|
||||
The first field found which matches is returned. This is especially important
|
||||
if index names or field names are used as those can be ambiguous.
|
||||
|
||||
For example, consider the following mapping:
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"article": {
|
||||
"properties": {
|
||||
"id": { "type": "string" },
|
||||
"title": { "type": "string", "index_name": "text" },
|
||||
"abstract": { "type": "string", "index_name": "text" },
|
||||
"author": {
|
||||
"properties": {
|
||||
"id": { "type": "string" },
|
||||
"name": { "type": "string", "index_name": "author" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
||||
To select the `id` of the `author` field, you can use it's full name `author.id`. Using `text` will return
|
||||
the mapping of `abstract` as it is one of the fields which map to the Lucene field `text`. `name` will return
|
||||
the field `author.name`:
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
curl -XGET "http://localhost:9200/publications/article/_mapping/field/author.id,text,name"
|
||||
--------------------------------------------------
|
||||
|
||||
returns:
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"publications": {
|
||||
"article": {
|
||||
"text": {
|
||||
"full_name": "abstract",
|
||||
"mapping": {
|
||||
"abstract": { "type": "string", "index_name": "text" }
|
||||
}
|
||||
},
|
||||
"author.id": {
|
||||
"full_name": "author.id",
|
||||
"mapping": {
|
||||
"id": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"full_name": "author.name",
|
||||
"mapping": {
|
||||
"name": { "type": "string", "index_name": "author" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
||||
Note how the response always use the same fields specified in the request as keys.
|
||||
The `full_name` in every entry contains the full name of the field whose mapping were returned.
|
||||
This is useful when the request can refer to to multiple fields (like `text` above).
|
||||
|
||||
[float]
|
||||
=== Other options
|
||||
|
||||
[horizontal]
|
||||
include_defaults:: adding `include_defaults=true` to the query string will cause the response to
|
||||
include default values, which are normally suppressed.
|
|
@ -6,7 +6,7 @@ index/type.
|
|||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
$ curl -XGET 'http://localhost:9200/twitter/tweet/_mapping'
|
||||
curl -XGET 'http://localhost:9200/twitter/tweet/_mapping'
|
||||
--------------------------------------------------
|
||||
|
||||
[float]
|
||||
|
@ -21,9 +21,9 @@ following are some examples:
|
|||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
$ curl -XGET 'http://localhost:9200/twitter,kimchy/_mapping'
|
||||
curl -XGET 'http://localhost:9200/twitter,kimchy/_mapping'
|
||||
|
||||
$ curl -XGET 'http://localhost:9200/_all/tweet,book/_mapping'
|
||||
curl -XGET 'http://localhost:9200/_all/tweet,book/_mapping'
|
||||
--------------------------------------------------
|
||||
|
||||
If you want to get mappings of all indices and types then the following
|
||||
|
@ -31,7 +31,7 @@ two examples are equivalent:
|
|||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
$ curl -XGET 'http://localhost:9200/_all/_mapping'
|
||||
curl -XGET 'http://localhost:9200/_all/_mapping'
|
||||
|
||||
$ curl -XGET 'http://localhost:9200/_mapping'
|
||||
curl -XGET 'http://localhost:9200/_mapping'
|
||||
--------------------------------------------------
|
||||
|
|
|
@ -68,7 +68,9 @@ import org.elasticsearch.action.admin.indices.gateway.snapshot.GatewaySnapshotAc
|
|||
import org.elasticsearch.action.admin.indices.gateway.snapshot.TransportGatewaySnapshotAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.delete.DeleteMappingAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.delete.TransportDeleteMappingAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.TransportGetFieldMappingsAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.TransportGetMappingsAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.TransportPutMappingAction;
|
||||
|
@ -200,6 +202,7 @@ public class ActionModule extends AbstractModule {
|
|||
registerAction(IndicesExistsAction.INSTANCE, TransportIndicesExistsAction.class);
|
||||
registerAction(TypesExistsAction.INSTANCE, TransportTypesExistsAction.class);
|
||||
registerAction(GetMappingsAction.INSTANCE, TransportGetMappingsAction.class);
|
||||
registerAction(GetFieldMappingsAction.INSTANCE, TransportGetFieldMappingsAction.class);
|
||||
registerAction(PutMappingAction.INSTANCE, TransportPutMappingAction.class);
|
||||
registerAction(DeleteMappingAction.INSTANCE, TransportDeleteMappingAction.class);
|
||||
registerAction(IndicesAliasesAction.INSTANCE, TransportIndicesAliasesAction.class);
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch licenses this
|
||||
* file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.indices.mapping.get;
|
||||
|
||||
import org.elasticsearch.action.admin.indices.IndicesAction;
|
||||
import org.elasticsearch.client.IndicesAdminClient;
|
||||
import org.elasticsearch.client.internal.InternalGenericClient;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class GetFieldMappingsAction extends IndicesAction<GetFieldMappingsRequest, GetFieldMappingsResponse, GetFieldMappingsRequestBuilder> {
|
||||
|
||||
public static final GetFieldMappingsAction INSTANCE = new GetFieldMappingsAction();
|
||||
public static final String NAME = "mappings/fields/get";
|
||||
|
||||
private GetFieldMappingsAction() {
|
||||
super(NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetFieldMappingsRequestBuilder newRequestBuilder(IndicesAdminClient client) {
|
||||
return new GetFieldMappingsRequestBuilder((InternalGenericClient) client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetFieldMappingsResponse newResponse() {
|
||||
return new GetFieldMappingsResponse();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch licenses this
|
||||
* file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.indices.mapping.get;
|
||||
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.action.support.master.info.ClusterInfoRequest;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/** Request the mappings of specific fields */
|
||||
public class GetFieldMappingsRequest extends ClusterInfoRequest<GetFieldMappingsRequest> {
|
||||
|
||||
private String[] fields = Strings.EMPTY_ARRAY;
|
||||
|
||||
private boolean includeDefaults = false;
|
||||
|
||||
/** @param fields a list of fields to retrieve the mapping for */
|
||||
public GetFieldMappingsRequest fields(String... fields) {
|
||||
this.fields = fields;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String[] fields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public boolean includeDefaults() {
|
||||
return includeDefaults;
|
||||
}
|
||||
|
||||
/** Indicates whether default mapping settings should be returned */
|
||||
public GetFieldMappingsRequest includeDefaults(boolean includeDefaults) {
|
||||
this.includeDefaults = includeDefaults;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionRequestValidationException validate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
out.writeStringArray(fields);
|
||||
out.writeBoolean(includeDefaults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
super.readFrom(in);
|
||||
fields = in.readStringArray();
|
||||
includeDefaults = in.readBoolean();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch licenses this
|
||||
* file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.indices.mapping.get;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.support.master.info.ClusterInfoRequestBuilder;
|
||||
import org.elasticsearch.client.IndicesAdminClient;
|
||||
import org.elasticsearch.client.internal.InternalGenericClient;
|
||||
|
||||
/** A helper class to build {@link GetFieldMappingsRequest} objects */
|
||||
public class GetFieldMappingsRequestBuilder extends ClusterInfoRequestBuilder<GetFieldMappingsRequest, GetFieldMappingsResponse, GetFieldMappingsRequestBuilder> {
|
||||
|
||||
public GetFieldMappingsRequestBuilder(InternalGenericClient client, String... indices) {
|
||||
super(client, new GetFieldMappingsRequest().indices(indices));
|
||||
}
|
||||
|
||||
|
||||
/** Sets the fields to retrieve. */
|
||||
public GetFieldMappingsRequestBuilder setFields(String... fields) {
|
||||
request.fields(fields);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Indicates whether default mapping settings should be returned */
|
||||
public GetFieldMappingsRequestBuilder includeDefaults(boolean includeDefaults) {
|
||||
request.includeDefaults(includeDefaults);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doExecute(ActionListener<GetFieldMappingsResponse> listener) {
|
||||
((IndicesAdminClient) client).getFieldMappings(request, listener);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch licenses this
|
||||
* file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.indices.mapping.get;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||
import org.elasticsearch.index.mapper.Mapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/** Response object for {@link GetFieldMappingsRequest} API */
|
||||
public class GetFieldMappingsResponse extends ActionResponse implements ToXContent {
|
||||
|
||||
private ImmutableMap<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> mappings = ImmutableMap.of();
|
||||
|
||||
GetFieldMappingsResponse(ImmutableMap<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> mappings) {
|
||||
this.mappings = mappings;
|
||||
}
|
||||
|
||||
GetFieldMappingsResponse() {
|
||||
}
|
||||
|
||||
/** returns the retrieved field mapping. The return map keys are index, type, field (as specified in the request). */
|
||||
public ImmutableMap<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> mappings() {
|
||||
return mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mappings of a specific field.
|
||||
*
|
||||
* @param field field name as specified in the {@link GetFieldMappingsRequest}
|
||||
* @return FieldMappingMetaData for the requested field or null if not found.
|
||||
*/
|
||||
public FieldMappingMetaData fieldMappings(String index, String type, String field) {
|
||||
ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>> indexMapping = mappings.get(index);
|
||||
if (indexMapping == null) {
|
||||
return null;
|
||||
}
|
||||
ImmutableMap<String, FieldMappingMetaData> typeMapping = indexMapping.get(type);
|
||||
if (typeMapping == null) {
|
||||
return null;
|
||||
}
|
||||
return typeMapping.get(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
for (Map.Entry<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> indexEntry : mappings.entrySet()) {
|
||||
builder.startObject(indexEntry.getKey(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
for (Map.Entry<String, ImmutableMap<String, FieldMappingMetaData>> typeEntry : indexEntry.getValue().entrySet()) {
|
||||
builder.startObject(typeEntry.getKey(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : typeEntry.getValue().entrySet()) {
|
||||
builder.startObject(fieldEntry.getKey());
|
||||
fieldEntry.getValue().toXContent(builder, params);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static class FieldMappingMetaData implements ToXContent {
|
||||
private String fullName;
|
||||
private BytesReference source;
|
||||
|
||||
public FieldMappingMetaData(String fullName, BytesReference source) {
|
||||
this.fullName = fullName;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public String fullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/** Returns the mappings as a map. Note that the returned map has a single key which is always the field's {@link Mapper#name}. */
|
||||
public Map<String, Object> sourceAsMap() {
|
||||
return XContentHelper.convertToMap(source.array(), source.arrayOffset(), source.length(), true).v2();
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.field("full_name", fullName);
|
||||
XContentHelper.writeRawField("mapping", source, builder, params);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
super.readFrom(in);
|
||||
int size = in.readVInt();
|
||||
ImmutableMap.Builder<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> indexMapBuilder = ImmutableMap.builder();
|
||||
for (int i = 0; i < size; i++) {
|
||||
String index = in.readString();
|
||||
int typesSize = in.readVInt();
|
||||
ImmutableMap.Builder<String, ImmutableMap<String, FieldMappingMetaData>> typeMapBuilder = ImmutableMap.builder();
|
||||
for (int j = 0; j < typesSize; j++) {
|
||||
String type = in.readString();
|
||||
ImmutableMap.Builder<String, FieldMappingMetaData> fieldMapBuilder = ImmutableMap.builder();
|
||||
int fieldSize = in.readVInt();
|
||||
for (int k = 0; k < fieldSize; k++) {
|
||||
fieldMapBuilder.put(in.readString(), new FieldMappingMetaData(in.readString(), in.readBytesReference()));
|
||||
}
|
||||
typeMapBuilder.put(type, fieldMapBuilder.build());
|
||||
}
|
||||
indexMapBuilder.put(index, typeMapBuilder.build());
|
||||
}
|
||||
mappings = indexMapBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
out.writeVInt(mappings.size());
|
||||
for (Map.Entry<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> indexEntry : mappings.entrySet()) {
|
||||
out.writeString(indexEntry.getKey());
|
||||
out.writeVInt(indexEntry.getValue().size());
|
||||
for (Map.Entry<String, ImmutableMap<String, FieldMappingMetaData>> typeEntry : indexEntry.getValue().entrySet()) {
|
||||
out.writeString(typeEntry.getKey());
|
||||
out.writeVInt(typeEntry.getValue().size());
|
||||
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : typeEntry.getValue().entrySet()) {
|
||||
out.writeString(fieldEntry.getKey());
|
||||
FieldMappingMetaData fieldMapping = fieldEntry.getValue();
|
||||
out.writeString(fieldMapping.fullName());
|
||||
out.writeBytesReference(fieldMapping.source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch licenses this
|
||||
* file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.indices.mapping.get;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.elasticsearch.ElasticSearchException;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData;
|
||||
import org.elasticsearch.action.support.master.info.TransportClusterInfoAction;
|
||||
import org.elasticsearch.cluster.ClusterService;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.common.collect.MapBuilder;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.regex.Regex;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.service.IndexService;
|
||||
import org.elasticsearch.indices.IndicesService;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class TransportGetFieldMappingsAction extends TransportClusterInfoAction<GetFieldMappingsRequest, GetFieldMappingsResponse> {
|
||||
|
||||
private final IndicesService indicesService;
|
||||
|
||||
@Inject
|
||||
public TransportGetFieldMappingsAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
||||
IndicesService indicesService, ThreadPool threadPool) {
|
||||
super(settings, transportService, clusterService, threadPool);
|
||||
this.indicesService = indicesService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String transportAction() {
|
||||
return GetFieldMappingsAction.NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetFieldMappingsRequest newRequest() {
|
||||
return new GetFieldMappingsRequest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetFieldMappingsResponse newResponse() {
|
||||
return new GetFieldMappingsResponse();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doMasterOperation(final GetFieldMappingsRequest request, final ClusterState state, final ActionListener<GetFieldMappingsResponse> listener) throws ElasticSearchException {
|
||||
|
||||
listener.onResponse(new GetFieldMappingsResponse(findMappings(request.indices(), request.types(), request.fields(), request.includeDefaults())));
|
||||
}
|
||||
|
||||
private ImmutableMap<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> findMappings(String[] concreteIndices,
|
||||
final String[] types,
|
||||
final String[] fields,
|
||||
boolean includeDefaults) {
|
||||
assert types != null;
|
||||
assert concreteIndices != null;
|
||||
if (concreteIndices.length == 0) {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
|
||||
ImmutableMap.Builder<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> indexMapBuilder = ImmutableMap.builder();
|
||||
Sets.SetView<String> intersection = Sets.intersection(Sets.newHashSet(concreteIndices), indicesService.indices());
|
||||
for (String index : intersection) {
|
||||
IndexService indexService = indicesService.indexService(index);
|
||||
Collection<String> typeIntersection;
|
||||
if (types.length == 0) {
|
||||
typeIntersection = indexService.mapperService().types();
|
||||
|
||||
} else {
|
||||
typeIntersection = Collections2.filter(indexService.mapperService().types(), new Predicate<String>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(String type) {
|
||||
return Regex.simpleMatch(types, type);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
MapBuilder<String, ImmutableMap<String, FieldMappingMetaData>> typeMappings = new MapBuilder<String, ImmutableMap<String, FieldMappingMetaData>>();
|
||||
for (String type : typeIntersection) {
|
||||
DocumentMapper documentMapper = indexService.mapperService().documentMapper(type);
|
||||
ImmutableMap<String, FieldMappingMetaData> fieldMapping = findFieldMappingsByType(documentMapper, fields, includeDefaults);
|
||||
if (!fieldMapping.isEmpty()) {
|
||||
typeMappings.put(type, fieldMapping);
|
||||
}
|
||||
}
|
||||
|
||||
if (!typeMappings.isEmpty()) {
|
||||
indexMapBuilder.put(index, typeMappings.immutableMap());
|
||||
}
|
||||
}
|
||||
|
||||
return indexMapBuilder.build();
|
||||
}
|
||||
|
||||
private static final ToXContent.Params includeDefaultsParams = new ToXContent.Params() {
|
||||
|
||||
final static String INCLUDE_DEFAULTS = "include_defaults";
|
||||
|
||||
@Override
|
||||
public String param(String key) {
|
||||
if (INCLUDE_DEFAULTS.equals(key)) {
|
||||
return "true";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String param(String key, String defaultValue) {
|
||||
if (INCLUDE_DEFAULTS.equals(key)) {
|
||||
return "true";
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean paramAsBoolean(String key, boolean defaultValue) {
|
||||
if (INCLUDE_DEFAULTS.equals(key)) {
|
||||
return true;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean paramAsBooleanOptional(String key, Boolean defaultValue) {
|
||||
if (INCLUDE_DEFAULTS.equals(key)) {
|
||||
return true;
|
||||
}
|
||||
return defaultValue;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private ImmutableMap<String, FieldMappingMetaData> findFieldMappingsByType(DocumentMapper documentMapper, String[] fields,
|
||||
boolean includeDefaults) throws ElasticSearchException {
|
||||
MapBuilder<String, FieldMappingMetaData> fieldMappings = new MapBuilder<String, FieldMappingMetaData>();
|
||||
for (String field : fields) {
|
||||
FieldMapper fieldMapper = documentMapper.mappers().smartNameFieldMapper(field);
|
||||
if (fieldMapper != null) {
|
||||
try {
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
|
||||
builder.startObject();
|
||||
fieldMapper.toXContent(builder, includeDefaults ? includeDefaultsParams : ToXContent.EMPTY_PARAMS);
|
||||
builder.endObject();
|
||||
fieldMappings.put(field, new FieldMappingMetaData(fieldMapper.names().fullName(), builder.bytes()));
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchException("failed to serialize XContent of field [" + field + "]", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return fieldMappings.immutableMap();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -59,9 +59,7 @@ import org.elasticsearch.action.admin.indices.gateway.snapshot.GatewaySnapshotRe
|
|||
import org.elasticsearch.action.admin.indices.mapping.delete.DeleteMappingRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.delete.DeleteMappingRequestBuilder;
|
||||
import org.elasticsearch.action.admin.indices.mapping.delete.DeleteMappingResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequestBuilder;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.*;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
|
||||
|
@ -398,12 +396,36 @@ public interface IndicesAdminClient {
|
|||
*/
|
||||
OptimizeRequestBuilder prepareOptimize(String... indices);
|
||||
|
||||
/**
|
||||
* Get the complete mappings of one or more types
|
||||
*/
|
||||
void getMappings(GetMappingsRequest request, ActionListener<GetMappingsResponse> listener);
|
||||
|
||||
/**
|
||||
* Get the complete mappings of one or more types
|
||||
*/
|
||||
ActionFuture<GetMappingsResponse> getMappings(GetMappingsRequest request);
|
||||
|
||||
/**
|
||||
* Get the complete mappings of one or more types
|
||||
*/
|
||||
GetMappingsRequestBuilder prepareGetMappings(String... indices);
|
||||
|
||||
/**
|
||||
* Get the mappings of specific fields
|
||||
*/
|
||||
void getFieldMappings(GetFieldMappingsRequest request, ActionListener<GetFieldMappingsResponse> listener);
|
||||
|
||||
/**
|
||||
* Get the mappings of specific fields
|
||||
*/
|
||||
GetFieldMappingsRequestBuilder prepareGetFieldMappings(String... indices);
|
||||
|
||||
/**
|
||||
* Get the mappings of specific fields
|
||||
*/
|
||||
ActionFuture<GetFieldMappingsResponse> getFieldMappings(GetFieldMappingsRequest request);
|
||||
|
||||
/**
|
||||
* Add mapping definition for a type into one or more indices.
|
||||
*
|
||||
|
|
|
@ -72,10 +72,7 @@ import org.elasticsearch.action.admin.indices.mapping.delete.DeleteMappingAction
|
|||
import org.elasticsearch.action.admin.indices.mapping.delete.DeleteMappingRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.delete.DeleteMappingRequestBuilder;
|
||||
import org.elasticsearch.action.admin.indices.mapping.delete.DeleteMappingResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequestBuilder;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.*;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder;
|
||||
|
@ -334,6 +331,11 @@ public abstract class AbstractIndicesAdminClient implements InternalIndicesAdmin
|
|||
execute(GetMappingsAction.INSTANCE, request, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getFieldMappings(GetFieldMappingsRequest request, ActionListener<GetFieldMappingsResponse> listener) {
|
||||
execute(GetFieldMappingsAction.INSTANCE, request, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetMappingsRequestBuilder prepareGetMappings(String... indices) {
|
||||
return new GetMappingsRequestBuilder(this, indices);
|
||||
|
@ -344,6 +346,16 @@ public abstract class AbstractIndicesAdminClient implements InternalIndicesAdmin
|
|||
return execute(GetMappingsAction.INSTANCE, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetFieldMappingsRequestBuilder prepareGetFieldMappings(String... indices) {
|
||||
return new GetFieldMappingsRequestBuilder(this, indices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionFuture<GetFieldMappingsResponse> getFieldMappings(GetFieldMappingsRequest request) {
|
||||
return execute(GetFieldMappingsAction.INSTANCE, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionFuture<PutMappingResponse> putMapping(final PutMappingRequest request) {
|
||||
return execute(PutMappingAction.INSTANCE, request);
|
||||
|
|
|
@ -76,6 +76,10 @@ public class MapBuilder<K, V> {
|
|||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
public Map<K, V> map() {
|
||||
return this.map;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ public class CodecService extends AbstractIndexComponent {
|
|||
private final MapperService mapperService;
|
||||
private final ImmutableMap<String, Codec> codecs;
|
||||
|
||||
public final static String DEFAULT_CODEC = "default";
|
||||
|
||||
public CodecService(Index index) {
|
||||
this(index, ImmutableSettings.Builder.EMPTY_SETTINGS);
|
||||
}
|
||||
|
@ -66,9 +68,11 @@ public class CodecService extends AbstractIndexComponent {
|
|||
this.mapperService = mapperService;
|
||||
MapBuilder<String, Codec> codecs = MapBuilder.<String, Codec>newMapBuilder();
|
||||
if (mapperService == null) {
|
||||
codecs.put("default", Codec.getDefault());
|
||||
codecs.put(DEFAULT_CODEC, Codec.getDefault());
|
||||
} else {
|
||||
codecs.put("default", new PerFieldMappingPostingFormatCodec(mapperService, postingsFormatService.get("default").get(), docValuesFormatService.get("default").get(), logger));
|
||||
codecs.put(DEFAULT_CODEC, new PerFieldMappingPostingFormatCodec(mapperService,
|
||||
postingsFormatService.get(PostingsFormatService.DEFAULT_FORMAT).get(),
|
||||
docValuesFormatService.get(DocValuesFormatService.DEFAULT_FORMAT).get(), logger));
|
||||
}
|
||||
for (String codec : Codec.availableCodecs()) {
|
||||
codecs.put(codec, Codec.forName(codec));
|
||||
|
|
|
@ -38,12 +38,13 @@ import java.util.Map;
|
|||
* {@link DocValuesFormatProvider#name() name}.
|
||||
*
|
||||
* @see CodecService
|
||||
*
|
||||
*/
|
||||
public class DocValuesFormatService extends AbstractIndexComponent {
|
||||
|
||||
private final ImmutableMap<String, DocValuesFormatProvider> providers;
|
||||
|
||||
public final static String DEFAULT_FORMAT = "default";
|
||||
|
||||
public DocValuesFormatService(Index index) {
|
||||
this(index, ImmutableSettings.Builder.EMPTY_SETTINGS);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class DocValuesFormats {
|
|||
builtInDocValuesFormatsX.put(name, new PreBuiltDocValuesFormatProvider.Factory(DocValuesFormat.forName(name)));
|
||||
}
|
||||
// LUCENE UPGRADE: update those DVF if necessary
|
||||
builtInDocValuesFormatsX.put("default", new PreBuiltDocValuesFormatProvider.Factory("default", DocValuesFormat.forName("Lucene45")));
|
||||
builtInDocValuesFormatsX.put(DocValuesFormatService.DEFAULT_FORMAT, new PreBuiltDocValuesFormatProvider.Factory(DocValuesFormatService.DEFAULT_FORMAT, DocValuesFormat.forName("Lucene45")));
|
||||
builtInDocValuesFormatsX.put("memory", new PreBuiltDocValuesFormatProvider.Factory("memory", DocValuesFormat.forName("Memory")));
|
||||
builtInDocValuesFormatsX.put("disk", new PreBuiltDocValuesFormatProvider.Factory("disk", DocValuesFormat.forName("Disk")));
|
||||
builtInDocValuesFormats = builtInDocValuesFormatsX.immutableMap();
|
||||
|
|
|
@ -71,7 +71,7 @@ public class PostingFormats {
|
|||
buildInPostingFormatsX.put("memory", new PreBuiltPostingsFormatProvider.Factory("memory", PostingsFormat.forName("Memory")));
|
||||
// LUCENE UPGRADE: Need to change this to the relevant ones on a lucene upgrade
|
||||
buildInPostingFormatsX.put("pulsing", new PreBuiltPostingsFormatProvider.Factory("pulsing", PostingsFormat.forName("Pulsing41")));
|
||||
buildInPostingFormatsX.put("default", new PreBuiltPostingsFormatProvider.Factory("default", defaultFormat));
|
||||
buildInPostingFormatsX.put(PostingsFormatService.DEFAULT_FORMAT, new PreBuiltPostingsFormatProvider.Factory(PostingsFormatService.DEFAULT_FORMAT, defaultFormat));
|
||||
|
||||
buildInPostingFormatsX.put("bloom_pulsing", new PreBuiltPostingsFormatProvider.Factory("bloom_pulsing", wrapInBloom(PostingsFormat.forName("Pulsing41"))));
|
||||
buildInPostingFormatsX.put("bloom_default", new PreBuiltPostingsFormatProvider.Factory("bloom_default", wrapInBloom(PostingsFormat.forName("Lucene41"))));
|
||||
|
|
|
@ -38,12 +38,13 @@ import java.util.Map;
|
|||
* {@link PostingsFormatProvider#name() name}.
|
||||
*
|
||||
* @see CodecService
|
||||
*
|
||||
*/
|
||||
public class PostingsFormatService extends AbstractIndexComponent {
|
||||
|
||||
private final ImmutableMap<String, PostingsFormatProvider> providers;
|
||||
|
||||
public final static String DEFAULT_FORMAT = "default";
|
||||
|
||||
public PostingsFormatService(Index index) {
|
||||
this(index, ImmutableSettings.Builder.EMPTY_SETTINGS);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import java.util.List;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public interface FieldMapper<T> {
|
||||
public interface FieldMapper<T> extends Mapper {
|
||||
|
||||
public static final String DOC_VALUES_FORMAT = "doc_values_format";
|
||||
|
||||
|
|
|
@ -39,11 +39,14 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.codec.docvaluesformat.DocValuesFormatProvider;
|
||||
import org.elasticsearch.index.codec.docvaluesformat.DocValuesFormatService;
|
||||
import org.elasticsearch.index.codec.postingsformat.PostingFormats;
|
||||
import org.elasticsearch.index.codec.postingsformat.PostingsFormatProvider;
|
||||
import org.elasticsearch.index.codec.postingsformat.PostingsFormatService;
|
||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||
import org.elasticsearch.index.mapper.*;
|
||||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
import org.elasticsearch.index.similarity.SimilarityLookupService;
|
||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -54,7 +57,7 @@ import java.util.Map;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractFieldMapper<T> implements FieldMapper<T>, Mapper {
|
||||
public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
|
||||
|
||||
public static class Defaults {
|
||||
public static final FieldType FIELD_TYPE = new FieldType();
|
||||
|
@ -350,9 +353,7 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T>, Mapper {
|
|||
/** Parse the field value and populate <code>fields</code>. */
|
||||
protected abstract void parseCreateField(ParseContext context, List<Field> fields) throws IOException;
|
||||
|
||||
/**
|
||||
* Derived classes can override it to specify that boost value is set by derived classes.
|
||||
*/
|
||||
/** Derived classes can override it to specify that boost value is set by derived classes. */
|
||||
protected boolean customBoost() {
|
||||
return false;
|
||||
}
|
||||
|
@ -550,68 +551,103 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T>, Mapper {
|
|||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(names.name());
|
||||
doXContentBody(builder);
|
||||
builder.endObject();
|
||||
return builder;
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
doXContentBody(builder, includeDefaults, params);
|
||||
return builder.endObject();
|
||||
}
|
||||
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
|
||||
builder.field("type", contentType());
|
||||
if (!names.name().equals(names.indexNameClean())) {
|
||||
if (includeDefaults || !names.name().equals(names.indexNameClean())) {
|
||||
builder.field("index_name", names.indexNameClean());
|
||||
}
|
||||
|
||||
if (boost != 1.0f) {
|
||||
if (includeDefaults || boost != 1.0f) {
|
||||
builder.field("boost", boost);
|
||||
}
|
||||
|
||||
FieldType defaultFieldType = defaultFieldType();
|
||||
if (fieldType.indexed() != defaultFieldType.indexed() ||
|
||||
if (includeDefaults || fieldType.indexed() != defaultFieldType.indexed() ||
|
||||
fieldType.tokenized() != defaultFieldType.tokenized()) {
|
||||
builder.field("index", indexTokenizeOptionToString(fieldType.indexed(), fieldType.tokenized()));
|
||||
}
|
||||
if (fieldType.stored() != defaultFieldType.stored()) {
|
||||
if (includeDefaults || fieldType.stored() != defaultFieldType.stored()) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
if (fieldType.storeTermVectors() != defaultFieldType.storeTermVectors()) {
|
||||
if (includeDefaults || fieldType.storeTermVectors() != defaultFieldType.storeTermVectors()) {
|
||||
builder.field("term_vector", termVectorOptionsToString(fieldType));
|
||||
}
|
||||
if (fieldType.omitNorms() != defaultFieldType.omitNorms()) {
|
||||
if (includeDefaults || fieldType.omitNorms() != defaultFieldType.omitNorms()) {
|
||||
builder.field("omit_norms", fieldType.omitNorms());
|
||||
}
|
||||
if (fieldType.indexOptions() != defaultFieldType.indexOptions()) {
|
||||
if (includeDefaults || fieldType.indexOptions() != defaultFieldType.indexOptions()) {
|
||||
builder.field("index_options", indexOptionToString(fieldType.indexOptions()));
|
||||
}
|
||||
|
||||
if (indexAnalyzer != null && searchAnalyzer != null && indexAnalyzer.name().equals(searchAnalyzer.name()) && !indexAnalyzer.name().startsWith("_") && !indexAnalyzer.name().equals("default")) {
|
||||
// same analyzers, output it once
|
||||
builder.field("analyzer", indexAnalyzer.name());
|
||||
} else {
|
||||
if (indexAnalyzer != null && !indexAnalyzer.name().startsWith("_") && !indexAnalyzer.name().equals("default")) {
|
||||
if (indexAnalyzer == null && searchAnalyzer == null) {
|
||||
if (includeDefaults) {
|
||||
builder.field("analyzer", "default");
|
||||
}
|
||||
} else if (indexAnalyzer == null) {
|
||||
// searchAnalyzer != null
|
||||
if (includeDefaults || (!searchAnalyzer.name().startsWith("_") && !searchAnalyzer.name().equals("default"))) {
|
||||
builder.field("search_analyzer", searchAnalyzer.name());
|
||||
}
|
||||
} else if (searchAnalyzer == null) {
|
||||
// indexAnalyzer != null
|
||||
if (includeDefaults || (!indexAnalyzer.name().startsWith("_") && !indexAnalyzer.name().equals("default"))) {
|
||||
builder.field("index_analyzer", indexAnalyzer.name());
|
||||
}
|
||||
if (searchAnalyzer != null && !searchAnalyzer.name().startsWith("_") && !searchAnalyzer.name().equals("default")) {
|
||||
} else if (indexAnalyzer.name().equals(searchAnalyzer.name())) {
|
||||
// indexAnalyzer == searchAnalyzer
|
||||
if (includeDefaults || (!indexAnalyzer.name().startsWith("_") && !indexAnalyzer.name().equals("default"))) {
|
||||
builder.field("analyzer", indexAnalyzer.name());
|
||||
}
|
||||
} else {
|
||||
// both are there but different
|
||||
if (includeDefaults || (!indexAnalyzer.name().startsWith("_") && !indexAnalyzer.name().equals("default"))) {
|
||||
builder.field("index_analyzer", indexAnalyzer.name());
|
||||
}
|
||||
if (includeDefaults || (!searchAnalyzer.name().startsWith("_") && !searchAnalyzer.name().equals("default"))) {
|
||||
builder.field("search_analyzer", searchAnalyzer.name());
|
||||
}
|
||||
}
|
||||
|
||||
if (postingsFormat != null) {
|
||||
if (!postingsFormat.name().equals(defaultPostingFormat())) {
|
||||
if (includeDefaults || !postingsFormat.name().equals(defaultPostingFormat())) {
|
||||
builder.field("postings_format", postingsFormat.name());
|
||||
}
|
||||
} else if (includeDefaults) {
|
||||
String format = defaultPostingFormat();
|
||||
if (format == null) {
|
||||
format = PostingsFormatService.DEFAULT_FORMAT;
|
||||
}
|
||||
builder.field("postings_format", format);
|
||||
}
|
||||
|
||||
if (docValuesFormat != null) {
|
||||
if (!docValuesFormat.name().equals(defaultDocValuesFormat())) {
|
||||
if (includeDefaults || !docValuesFormat.name().equals(defaultDocValuesFormat())) {
|
||||
builder.field(DOC_VALUES_FORMAT, docValuesFormat.name());
|
||||
}
|
||||
} else if (includeDefaults) {
|
||||
String format = defaultDocValuesFormat();
|
||||
if (format == null) {
|
||||
format = DocValuesFormatService.DEFAULT_FORMAT;
|
||||
}
|
||||
builder.field(DOC_VALUES_FORMAT, format);
|
||||
}
|
||||
|
||||
if (similarity() != null) {
|
||||
builder.field("similarity", similarity().name());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("similariry", SimilarityLookupService.DEFAULT_SIMILARITY);
|
||||
}
|
||||
|
||||
if (customFieldDataSettings != null) {
|
||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -200,23 +200,24 @@ public class BinaryFieldMapper extends AbstractFieldMapper<BytesReference> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(names.name());
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
builder.field("type", contentType());
|
||||
if (!names.name().equals(names.indexNameClean())) {
|
||||
if (includeDefaults || !names.name().equals(names.indexNameClean())) {
|
||||
builder.field("index_name", names.indexNameClean());
|
||||
}
|
||||
if (compress != null) {
|
||||
builder.field("compress", compress);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("compress", false);
|
||||
}
|
||||
if (compressThreshold != -1) {
|
||||
builder.field("compress_threshold", new ByteSizeValue(compressThreshold).toString());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("compress_threshold", -1);
|
||||
}
|
||||
if (fieldType.stored() != defaultFieldType().stored()) {
|
||||
if (includeDefaults || fieldType.stored() != defaultFieldType().stored()) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -227,9 +227,9 @@ public class BooleanFieldMapper extends AbstractFieldMapper<Boolean> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (nullValue != null) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -346,16 +346,19 @@ public class ByteFieldMapper extends NumberFieldMapper<Byte> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (precisionStep != Defaults.PRECISION_STEP) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
|
||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
|
||||
builder.field("precision_step", precisionStep);
|
||||
}
|
||||
if (nullValue != null) {
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
if (includeInAll != null) {
|
||||
builder.field("include_in_all", includeInAll);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("include_in_all", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -244,9 +244,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
return parseStringValue(value.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Dates should return as a string.
|
||||
*/
|
||||
/** Dates should return as a string. */
|
||||
@Override
|
||||
public Object valueForSearch(Object value) {
|
||||
if (value instanceof String) {
|
||||
|
@ -450,24 +448,34 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (precisionStep != Defaults.PRECISION_STEP) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
|
||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
|
||||
builder.field("precision_step", precisionStep);
|
||||
}
|
||||
builder.field("format", dateTimeFormatter.format());
|
||||
if (nullValue != null) {
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
if (includeInAll != null) {
|
||||
builder.field("include_in_all", includeInAll);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("include_in_all", false);
|
||||
}
|
||||
if (timeUnit != Defaults.TIME_UNIT) {
|
||||
|
||||
if (includeDefaults || timeUnit != Defaults.TIME_UNIT) {
|
||||
builder.field("numeric_resolution", timeUnit.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
// only serialize locale if needed, ROOT is the default, so no need to serialize that case as well...
|
||||
if (dateTimeFormatter.locale() != null && dateTimeFormatter.locale() != Locale.ROOT) {
|
||||
builder.field("locale", dateTimeFormatter.locale());
|
||||
} else if (includeDefaults) {
|
||||
if (dateTimeFormatter.locale() == null) {
|
||||
builder.field("locale", Locale.ROOT);
|
||||
} else {
|
||||
builder.field("locale", dateTimeFormatter.locale());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -342,17 +342,21 @@ public class DoubleFieldMapper extends NumberFieldMapper<Double> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (precisionStep != Defaults.PRECISION_STEP) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
|
||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
|
||||
builder.field("precision_step", precisionStep);
|
||||
}
|
||||
if (nullValue != null) {
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
if (includeInAll != null) {
|
||||
builder.field("include_in_all", includeInAll);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("include_in_all", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CustomDoubleNumericField extends CustomNumericField {
|
||||
|
|
|
@ -339,17 +339,21 @@ public class FloatFieldMapper extends NumberFieldMapper<Float> {
|
|||
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (precisionStep != Defaults.PRECISION_STEP) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
|
||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
|
||||
builder.field("precision_step", precisionStep);
|
||||
}
|
||||
if (nullValue != null) {
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
if (includeInAll != null) {
|
||||
builder.field("include_in_all", includeInAll);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("include_in_all", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CustomFloatNumericField extends CustomNumericField {
|
||||
|
|
|
@ -344,17 +344,21 @@ public class IntegerFieldMapper extends NumberFieldMapper<Integer> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (precisionStep != Defaults.PRECISION_STEP) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
|
||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
|
||||
builder.field("precision_step", precisionStep);
|
||||
}
|
||||
if (nullValue != null) {
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
if (includeInAll != null) {
|
||||
builder.field("include_in_all", includeInAll);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("include_in_all", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CustomIntegerNumericField extends CustomNumericField {
|
||||
|
|
|
@ -340,16 +340,19 @@ public class LongFieldMapper extends NumberFieldMapper<Long> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (precisionStep != Defaults.PRECISION_STEP) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
|
||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
|
||||
builder.field("precision_step", precisionStep);
|
||||
}
|
||||
if (nullValue != null) {
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
if (includeInAll != null) {
|
||||
builder.field("include_in_all", includeInAll);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("include_in_all", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -182,26 +182,34 @@ public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldM
|
|||
}
|
||||
}
|
||||
|
||||
/** Utility method to convert a long to a doc values field using {@link NumericUtils} encoding. */
|
||||
/**
|
||||
* Utility method to convert a long to a doc values field using {@link NumericUtils} encoding.
|
||||
*/
|
||||
protected final Field toDocValues(long l) {
|
||||
final BytesRef bytes = new BytesRef();
|
||||
NumericUtils.longToPrefixCoded(l, 0, bytes);
|
||||
return new SortedSetDocValuesField(names().indexName(), bytes);
|
||||
}
|
||||
|
||||
/** Utility method to convert an int to a doc values field using {@link NumericUtils} encoding. */
|
||||
/**
|
||||
* Utility method to convert an int to a doc values field using {@link NumericUtils} encoding.
|
||||
*/
|
||||
protected final Field toDocValues(int i) {
|
||||
final BytesRef bytes = new BytesRef();
|
||||
NumericUtils.intToPrefixCoded(i, 0, bytes);
|
||||
return new SortedSetDocValuesField(names().indexName(), bytes);
|
||||
}
|
||||
|
||||
/** Utility method to convert a float to a doc values field using {@link NumericUtils} encoding. */
|
||||
/**
|
||||
* Utility method to convert a float to a doc values field using {@link NumericUtils} encoding.
|
||||
*/
|
||||
protected final Field toDocValues(float f) {
|
||||
return toDocValues(NumericUtils.floatToSortableInt(f));
|
||||
}
|
||||
|
||||
/** Utility method to convert a double to a doc values field using {@link NumericUtils} encoding. */
|
||||
/**
|
||||
* Utility method to convert a double to a doc values field using {@link NumericUtils} encoding.
|
||||
*/
|
||||
protected final Field toDocValues(double d) {
|
||||
return toDocValues(NumericUtils.doubleToSortableLong(d));
|
||||
}
|
||||
|
@ -318,9 +326,10 @@ public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldM
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (ignoreMalformed.explicit()) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
|
||||
if (includeDefaults || ignoreMalformed.explicit()) {
|
||||
builder.field("ignore_malformed", ignoreMalformed.value());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -345,17 +345,21 @@ public class ShortFieldMapper extends NumberFieldMapper<Short> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (precisionStep != Defaults.PRECISION_STEP) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
|
||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
|
||||
builder.field("precision_step", precisionStep);
|
||||
}
|
||||
if (nullValue != null) {
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
if (includeInAll != null) {
|
||||
builder.field("include_in_all", includeInAll);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("include_in_all", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CustomShortNumericField extends CustomNumericField {
|
||||
|
|
|
@ -329,28 +329,36 @@ public class StringFieldMapper extends AbstractFieldMapper<String> implements Al
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (nullValue != null) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
if (includeInAll != null) {
|
||||
builder.field("include_in_all", includeInAll);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("include_in_all", false);
|
||||
}
|
||||
if (positionOffsetGap != Defaults.POSITION_OFFSET_GAP) {
|
||||
|
||||
if (includeDefaults || positionOffsetGap != Defaults.POSITION_OFFSET_GAP) {
|
||||
builder.field("position_offset_gap", positionOffsetGap);
|
||||
}
|
||||
if (searchQuotedAnalyzer != null && searchAnalyzer != searchQuotedAnalyzer) {
|
||||
builder.field("search_quote_analyzer", searchQuotedAnalyzer.name());
|
||||
} else if (includeDefaults) {
|
||||
if (searchQuotedAnalyzer == null) {
|
||||
builder.field("search_quote_analyzer", "default");
|
||||
} else {
|
||||
builder.field("search_quote_analyzer", searchQuotedAnalyzer.name());
|
||||
}
|
||||
if (ignoreAbove != Defaults.IGNORE_ABOVE) {
|
||||
}
|
||||
if (includeDefaults || ignoreAbove != Defaults.IGNORE_ABOVE) {
|
||||
builder.field("ignore_above", ignoreAbove);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension of {@link Field} supporting reuse of a cached TokenStream for not-tokenized values.
|
||||
*/
|
||||
/** Extension of {@link Field} supporting reuse of a cached TokenStream for not-tokenized values. */
|
||||
static class StringField extends Field {
|
||||
|
||||
public StringField(String name, String value, FieldType fieldType) {
|
||||
|
@ -394,9 +402,7 @@ public class StringFieldMapper extends AbstractFieldMapper<String> implements Al
|
|||
StringTokenStream() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the string value.
|
||||
*/
|
||||
/** Sets the string value. */
|
||||
StringTokenStream setValue(String value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
|
|
|
@ -220,7 +220,7 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper<String> {
|
|||
public void parse(ParseContext context) throws IOException {
|
||||
try {
|
||||
ShapeBuilder shape = ShapeBuilder.parse(context.parser());
|
||||
if(shape == null) {
|
||||
if (shape == null) {
|
||||
return;
|
||||
}
|
||||
Field[] fields = defaultStrategy.createIndexableFields(shape.build());
|
||||
|
@ -245,24 +245,24 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper<String> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
builder.field("type", contentType());
|
||||
|
||||
// TODO: Come up with a better way to get the name, maybe pass it from builder
|
||||
if (defaultStrategy.getGrid() instanceof GeohashPrefixTree) {
|
||||
// Don't emit the tree name since GeohashPrefixTree is the default
|
||||
// Only emit the tree levels if it isn't the default value
|
||||
if (defaultStrategy.getGrid().getMaxLevels() != Defaults.GEOHASH_LEVELS) {
|
||||
if (includeDefaults || defaultStrategy.getGrid().getMaxLevels() != Defaults.GEOHASH_LEVELS) {
|
||||
builder.field(Names.TREE_LEVELS, defaultStrategy.getGrid().getMaxLevels());
|
||||
}
|
||||
} else {
|
||||
builder.field(Names.TREE, Names.TREE_QUADTREE);
|
||||
if (defaultStrategy.getGrid().getMaxLevels() != Defaults.QUADTREE_LEVELS) {
|
||||
if (includeDefaults || defaultStrategy.getGrid().getMaxLevels() != Defaults.QUADTREE_LEVELS) {
|
||||
builder.field(Names.TREE_LEVELS, defaultStrategy.getGrid().getMaxLevels());
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultStrategy.getDistErrPct() != Defaults.DISTANCE_ERROR_PCT) {
|
||||
if (includeDefaults || defaultStrategy.getDistErrPct() != Defaults.DISTANCE_ERROR_PCT) {
|
||||
builder.field(Names.DISTANCE_ERROR_PCT, defaultStrategy.getDistErrPct());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.elasticsearch.index.fielddata.FieldDataType;
|
|||
import org.elasticsearch.index.mapper.*;
|
||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
import org.elasticsearch.index.similarity.SimilarityLookupService;
|
||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -256,50 +257,78 @@ public class AllFieldMapper extends AbstractFieldMapper<Void> implements Interna
|
|||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
// if all are defaults, no need to write it at all
|
||||
if (enabled == Defaults.ENABLED && fieldType.stored() == Defaults.FIELD_TYPE.stored() &&
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
if (!includeDefaults && enabled == Defaults.ENABLED && fieldType.stored() == Defaults.FIELD_TYPE.stored() &&
|
||||
fieldType.storeTermVectors() == Defaults.FIELD_TYPE.storeTermVectors() &&
|
||||
indexAnalyzer == null && searchAnalyzer == null && customFieldDataSettings == null) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
if (enabled != Defaults.ENABLED) {
|
||||
if (includeDefaults || enabled != Defaults.ENABLED) {
|
||||
builder.field("enabled", enabled);
|
||||
}
|
||||
if (autoBoost != false) {
|
||||
if (includeDefaults || autoBoost != false) {
|
||||
builder.field("auto_boost", autoBoost);
|
||||
}
|
||||
if (fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
if (includeDefaults || fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
if (fieldType.storeTermVectors() != Defaults.FIELD_TYPE.storeTermVectors()) {
|
||||
if (includeDefaults || fieldType.storeTermVectors() != Defaults.FIELD_TYPE.storeTermVectors()) {
|
||||
builder.field("store_term_vector", fieldType.storeTermVectors());
|
||||
}
|
||||
if (fieldType.storeTermVectorOffsets() != Defaults.FIELD_TYPE.storeTermVectorOffsets()) {
|
||||
if (includeDefaults || fieldType.storeTermVectorOffsets() != Defaults.FIELD_TYPE.storeTermVectorOffsets()) {
|
||||
builder.field("store_term_vector_offsets", fieldType.storeTermVectorOffsets());
|
||||
}
|
||||
if (fieldType.storeTermVectorPositions() != Defaults.FIELD_TYPE.storeTermVectorPositions()) {
|
||||
if (includeDefaults || fieldType.storeTermVectorPositions() != Defaults.FIELD_TYPE.storeTermVectorPositions()) {
|
||||
builder.field("store_term_vector_positions", fieldType.storeTermVectorPositions());
|
||||
}
|
||||
if (fieldType.storeTermVectorPayloads() != Defaults.FIELD_TYPE.storeTermVectorPayloads()) {
|
||||
if (includeDefaults || fieldType.storeTermVectorPayloads() != Defaults.FIELD_TYPE.storeTermVectorPayloads()) {
|
||||
builder.field("store_term_vector_payloads", fieldType.storeTermVectorPayloads());
|
||||
}
|
||||
if (indexAnalyzer != null && searchAnalyzer != null && indexAnalyzer.name().equals(searchAnalyzer.name()) && !indexAnalyzer.name().startsWith("_")) {
|
||||
// same analyzers, output it once
|
||||
builder.field("analyzer", indexAnalyzer.name());
|
||||
} else {
|
||||
if (indexAnalyzer != null && !indexAnalyzer.name().startsWith("_")) {
|
||||
|
||||
|
||||
if (indexAnalyzer == null && searchAnalyzer == null) {
|
||||
if (includeDefaults) {
|
||||
builder.field("analyzer", "default");
|
||||
}
|
||||
} else if (indexAnalyzer == null) {
|
||||
// searchAnalyzer != null
|
||||
if (includeDefaults || !searchAnalyzer.name().startsWith("_")) {
|
||||
builder.field("search_analyzer", searchAnalyzer.name());
|
||||
}
|
||||
} else if (searchAnalyzer == null) {
|
||||
// indexAnalyzer != null
|
||||
if (includeDefaults || !indexAnalyzer.name().startsWith("_")) {
|
||||
builder.field("index_analyzer", indexAnalyzer.name());
|
||||
}
|
||||
if (searchAnalyzer != null && !searchAnalyzer.name().startsWith("_")) {
|
||||
} else if (indexAnalyzer.name().equals(searchAnalyzer.name())) {
|
||||
// indexAnalyzer == searchAnalyzer
|
||||
if (includeDefaults || !indexAnalyzer.name().startsWith("_")) {
|
||||
builder.field("analyzer", indexAnalyzer.name());
|
||||
}
|
||||
} else {
|
||||
// both are there but different
|
||||
if (includeDefaults || !indexAnalyzer.name().startsWith("_")) {
|
||||
builder.field("index_analyzer", indexAnalyzer.name());
|
||||
}
|
||||
if (includeDefaults || !searchAnalyzer.name().startsWith("_")) {
|
||||
builder.field("search_analyzer", searchAnalyzer.name());
|
||||
}
|
||||
}
|
||||
|
||||
if (similarity() != null) {
|
||||
builder.field("similarity", similarity().name());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("similariry", SimilarityLookupService.DEFAULT_SIMILARITY);
|
||||
}
|
||||
|
||||
if (customFieldDataSettings != null) {
|
||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
||||
}
|
||||
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
|
|
@ -284,28 +284,33 @@ public class BoostFieldMapper extends NumberFieldMapper<Float> implements Intern
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// all are defaults, don't write it at all
|
||||
if (name().equals(Defaults.NAME) && nullValue == null &&
|
||||
if (!includeDefaults && name().equals(Defaults.NAME) && nullValue == null &&
|
||||
fieldType.indexed() == Defaults.FIELD_TYPE.indexed() &&
|
||||
fieldType.stored() == Defaults.FIELD_TYPE.stored() &&
|
||||
customFieldDataSettings == null) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(contentType());
|
||||
if (!name().equals(Defaults.NAME)) {
|
||||
if (includeDefaults || !name().equals(Defaults.NAME)) {
|
||||
builder.field("name", name());
|
||||
}
|
||||
if (nullValue != null) {
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
if (fieldType.indexed() != Defaults.FIELD_TYPE.indexed()) {
|
||||
if (includeDefaults || fieldType.indexed() != Defaults.FIELD_TYPE.indexed()) {
|
||||
builder.field("index", fieldType.indexed());
|
||||
}
|
||||
if (fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
if (includeDefaults || fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
if (customFieldDataSettings != null) {
|
||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
||||
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
|
|
|
@ -39,7 +39,9 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.codec.docvaluesformat.DocValuesFormatProvider;
|
||||
import org.elasticsearch.index.codec.docvaluesformat.DocValuesFormatService;
|
||||
import org.elasticsearch.index.codec.postingsformat.PostingsFormatProvider;
|
||||
import org.elasticsearch.index.codec.postingsformat.PostingsFormatService;
|
||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||
import org.elasticsearch.index.mapper.*;
|
||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||
|
@ -325,8 +327,10 @@ public class IdFieldMapper extends AbstractFieldMapper<String> implements Intern
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// if all are defaults, no sense to write it at all
|
||||
if (fieldType.stored() == Defaults.FIELD_TYPE.stored()
|
||||
if (!includeDefaults && fieldType.stored() == Defaults.FIELD_TYPE.stored()
|
||||
&& fieldType.indexed() == Defaults.FIELD_TYPE.indexed()
|
||||
&& path == Defaults.PATH
|
||||
&& customFieldDataSettings == null
|
||||
|
@ -335,23 +339,44 @@ public class IdFieldMapper extends AbstractFieldMapper<String> implements Intern
|
|||
return builder;
|
||||
}
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
if (fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
if (includeDefaults || fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
if (fieldType.indexed() != Defaults.FIELD_TYPE.indexed()) {
|
||||
if (includeDefaults || fieldType.indexed() != Defaults.FIELD_TYPE.indexed()) {
|
||||
builder.field("index", indexTokenizeOptionToString(fieldType.indexed(), fieldType.tokenized()));
|
||||
}
|
||||
if (path != Defaults.PATH) {
|
||||
if (includeDefaults || path != Defaults.PATH) {
|
||||
builder.field("path", path);
|
||||
}
|
||||
if (postingsFormat != null && !postingsFormat.name().equals(defaultPostingFormat())) {
|
||||
|
||||
if (postingsFormat != null) {
|
||||
if (includeDefaults || !postingsFormat.name().equals(defaultPostingFormat())) {
|
||||
builder.field("postings_format", postingsFormat.name());
|
||||
}
|
||||
if (docValuesFormat != null && !docValuesFormat.name().equals(defaultDocValuesFormat())) {
|
||||
} else if (includeDefaults) {
|
||||
String format = defaultPostingFormat();
|
||||
if (format == null) {
|
||||
format = PostingsFormatService.DEFAULT_FORMAT;
|
||||
}
|
||||
builder.field("postings_format", format);
|
||||
}
|
||||
|
||||
if (docValuesFormat != null) {
|
||||
if (includeDefaults || !docValuesFormat.name().equals(defaultDocValuesFormat())) {
|
||||
builder.field(DOC_VALUES_FORMAT, docValuesFormat.name());
|
||||
}
|
||||
} else if (includeDefaults) {
|
||||
String format = defaultDocValuesFormat();
|
||||
if (format == null) {
|
||||
format = DocValuesFormatService.DEFAULT_FORMAT;
|
||||
}
|
||||
builder.field(DOC_VALUES_FORMAT, format);
|
||||
}
|
||||
|
||||
if (customFieldDataSettings != null) {
|
||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
|
|
|
@ -195,19 +195,25 @@ public class IndexFieldMapper extends AbstractFieldMapper<String> implements Int
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// if all defaults, no need to write it at all
|
||||
if (fieldType().stored() == Defaults.FIELD_TYPE.stored() && enabledState == Defaults.ENABLED_STATE) {
|
||||
if (!includeDefaults && fieldType().stored() == Defaults.FIELD_TYPE.stored() && enabledState == Defaults.ENABLED_STATE) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
if (fieldType().stored() != Defaults.FIELD_TYPE.stored() && enabledState.enabled) {
|
||||
if (includeDefaults || fieldType().stored() != Defaults.FIELD_TYPE.stored() && enabledState.enabled) {
|
||||
builder.field("store", fieldType().stored());
|
||||
}
|
||||
if (enabledState != Defaults.ENABLED_STATE) {
|
||||
if (includeDefaults || enabledState != Defaults.ENABLED_STATE) {
|
||||
builder.field("enabled", enabledState.enabled);
|
||||
}
|
||||
|
||||
if (customFieldDataSettings != null) {
|
||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
||||
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
|
|
|
@ -238,22 +238,24 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// if all are defaults, no sense to write it at all
|
||||
if (fieldType.indexed() == Defaults.FIELD_TYPE.indexed() &&
|
||||
if (!includeDefaults && fieldType.indexed() == Defaults.FIELD_TYPE.indexed() &&
|
||||
fieldType.stored() == Defaults.FIELD_TYPE.stored() && required == Defaults.REQUIRED && path == Defaults.PATH) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
if (fieldType.indexed() != Defaults.FIELD_TYPE.indexed()) {
|
||||
if (includeDefaults || fieldType.indexed() != Defaults.FIELD_TYPE.indexed()) {
|
||||
builder.field("index", indexTokenizeOptionToString(fieldType.indexed(), fieldType.tokenized()));
|
||||
}
|
||||
if (fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
if (includeDefaults || fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
if (required != Defaults.REQUIRED) {
|
||||
if (includeDefaults || required != Defaults.REQUIRED) {
|
||||
builder.field("required", required);
|
||||
}
|
||||
if (path != Defaults.PATH) {
|
||||
if (includeDefaults || path != Defaults.PATH) {
|
||||
builder.field("path", path);
|
||||
}
|
||||
builder.endObject();
|
||||
|
|
|
@ -156,15 +156,17 @@ public class SizeFieldMapper extends IntegerFieldMapper implements RootMapper {
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// all are defaults, no need to write it at all
|
||||
if (enabledState == Defaults.ENABLED_STATE && fieldType().stored() == Defaults.SIZE_FIELD_TYPE.stored()) {
|
||||
if (!includeDefaults && enabledState == Defaults.ENABLED_STATE && fieldType().stored() == Defaults.SIZE_FIELD_TYPE.stored()) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(contentType());
|
||||
if (enabledState != Defaults.ENABLED_STATE) {
|
||||
if (includeDefaults || enabledState != Defaults.ENABLED_STATE) {
|
||||
builder.field("enabled", enabledState.enabled);
|
||||
}
|
||||
if (fieldType().stored() != Defaults.SIZE_FIELD_TYPE.stored() && enabledState.enabled) {
|
||||
if (includeDefaults || fieldType().stored() != Defaults.SIZE_FIELD_TYPE.stored() && enabledState.enabled) {
|
||||
builder.field("store", fieldType().stored());
|
||||
}
|
||||
builder.endObject();
|
||||
|
|
|
@ -370,29 +370,42 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// all are defaults, no need to write it at all
|
||||
if (enabled == Defaults.ENABLED && compress == null && compressThreshold == -1 && includes == null && excludes == null) {
|
||||
if (!includeDefaults && enabled == Defaults.ENABLED && compress == null && compressThreshold == -1 && includes == null && excludes == null) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(contentType());
|
||||
if (enabled != Defaults.ENABLED) {
|
||||
if (includeDefaults || enabled != Defaults.ENABLED) {
|
||||
builder.field("enabled", enabled);
|
||||
}
|
||||
if (!Objects.equal(format, Defaults.FORMAT)) {
|
||||
if (includeDefaults || !Objects.equal(format, Defaults.FORMAT)) {
|
||||
builder.field("format", format);
|
||||
}
|
||||
if (compress != null) {
|
||||
builder.field("compress", compress);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("compress", false);
|
||||
}
|
||||
if (compressThreshold != -1) {
|
||||
builder.field("compress_threshold", new ByteSizeValue(compressThreshold).toString());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("compress_threshold", -1);
|
||||
}
|
||||
|
||||
if (includes != null) {
|
||||
builder.field("includes", includes);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("includes", Strings.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
if (excludes != null) {
|
||||
builder.field("excludes", excludes);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("excludes", Strings.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
|
|
@ -221,15 +221,17 @@ public class TTLFieldMapper extends LongFieldMapper implements InternalMapper, R
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// if all are defaults, no sense to write it at all
|
||||
if (enabledState == Defaults.ENABLED_STATE && defaultTTL == Defaults.DEFAULT) {
|
||||
if (!includeDefaults && enabledState == Defaults.ENABLED_STATE && defaultTTL == Defaults.DEFAULT) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
if (enabledState != Defaults.ENABLED_STATE) {
|
||||
if (includeDefaults || enabledState != Defaults.ENABLED_STATE) {
|
||||
builder.field("enabled", enabledState.enabled);
|
||||
}
|
||||
if (defaultTTL != Defaults.DEFAULT && enabledState.enabled) {
|
||||
if (includeDefaults || defaultTTL != Defaults.DEFAULT && enabledState.enabled) {
|
||||
builder.field("default", defaultTTL);
|
||||
}
|
||||
builder.endObject();
|
||||
|
|
|
@ -224,32 +224,37 @@ public class TimestampFieldMapper extends DateFieldMapper implements InternalMap
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// if all are defaults, no sense to write it at all
|
||||
if (fieldType.indexed() == Defaults.FIELD_TYPE.indexed() && customFieldDataSettings == null &&
|
||||
if (!includeDefaults && fieldType.indexed() == Defaults.FIELD_TYPE.indexed() && customFieldDataSettings == null &&
|
||||
fieldType.stored() == Defaults.FIELD_TYPE.stored() && enabledState == Defaults.ENABLED && path == Defaults.PATH
|
||||
&& dateTimeFormatter.format().equals(Defaults.DATE_TIME_FORMATTER.format())) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
if (enabledState != Defaults.ENABLED) {
|
||||
if (includeDefaults || enabledState != Defaults.ENABLED) {
|
||||
builder.field("enabled", enabledState.enabled);
|
||||
}
|
||||
if (enabledState.enabled) {
|
||||
if (fieldType.indexed() != Defaults.FIELD_TYPE.indexed()) {
|
||||
if (includeDefaults || fieldType.indexed() != Defaults.FIELD_TYPE.indexed()) {
|
||||
builder.field("index", indexTokenizeOptionToString(fieldType.indexed(), fieldType.tokenized()));
|
||||
}
|
||||
if (fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
if (includeDefaults || fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
if (path != Defaults.PATH) {
|
||||
if (includeDefaults || path != Defaults.PATH) {
|
||||
builder.field("path", path);
|
||||
}
|
||||
if (!dateTimeFormatter.format().equals(Defaults.DATE_TIME_FORMATTER.format())) {
|
||||
if (includeDefaults || !dateTimeFormatter.format().equals(Defaults.DATE_TIME_FORMATTER.format())) {
|
||||
builder.field("format", dateTimeFormatter.format());
|
||||
}
|
||||
if (customFieldDataSettings != null) {
|
||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
||||
}
|
||||
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
|
|
|
@ -194,15 +194,17 @@ public class TypeFieldMapper extends AbstractFieldMapper<String> implements Inte
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// if all are defaults, no sense to write it at all
|
||||
if (fieldType.stored() == Defaults.FIELD_TYPE.stored() && fieldType.indexed() == Defaults.FIELD_TYPE.indexed()) {
|
||||
if (!includeDefaults && fieldType.stored() == Defaults.FIELD_TYPE.stored() && fieldType.indexed() == Defaults.FIELD_TYPE.indexed()) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
if (fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
if (includeDefaults || fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
if (fieldType.indexed() != Defaults.FIELD_TYPE.indexed()) {
|
||||
if (includeDefaults || fieldType.indexed() != Defaults.FIELD_TYPE.indexed()) {
|
||||
builder.field("index", indexTokenizeOptionToString(fieldType.indexed(), fieldType.tokenized()));
|
||||
}
|
||||
builder.endObject();
|
||||
|
|
|
@ -33,7 +33,9 @@ import org.elasticsearch.common.settings.ImmutableSettings;
|
|||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.codec.docvaluesformat.DocValuesFormatProvider;
|
||||
import org.elasticsearch.index.codec.docvaluesformat.DocValuesFormatService;
|
||||
import org.elasticsearch.index.codec.postingsformat.PostingsFormatProvider;
|
||||
import org.elasticsearch.index.codec.postingsformat.PostingsFormatService;
|
||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||
import org.elasticsearch.index.mapper.*;
|
||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||
|
@ -204,8 +206,10 @@ public class UidFieldMapper extends AbstractFieldMapper<Uid> implements Internal
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// if defaults, don't output
|
||||
if (customFieldDataSettings == null
|
||||
if (!includeDefaults && customFieldDataSettings == null
|
||||
&& (postingsFormat == null || postingsFormat.name().equals(defaultPostingFormat()))
|
||||
&& (docValuesFormat == null || docValuesFormat.name().equals(defaultDocValuesFormat()))) {
|
||||
return builder;
|
||||
|
@ -214,19 +218,33 @@ public class UidFieldMapper extends AbstractFieldMapper<Uid> implements Internal
|
|||
builder.startObject(CONTENT_TYPE);
|
||||
|
||||
if (postingsFormat != null) {
|
||||
if (!postingsFormat.name().equals(defaultPostingFormat())) {
|
||||
if (includeDefaults || !postingsFormat.name().equals(defaultPostingFormat())) {
|
||||
builder.field("postings_format", postingsFormat.name());
|
||||
}
|
||||
} else if (includeDefaults) {
|
||||
String format = defaultPostingFormat();
|
||||
if (format == null) {
|
||||
format = PostingsFormatService.DEFAULT_FORMAT;
|
||||
}
|
||||
builder.field("postings_format", format);
|
||||
}
|
||||
|
||||
if (docValuesFormat != null) {
|
||||
if (!docValuesFormat.equals(defaultDocValuesFormat())) {
|
||||
if (includeDefaults || !docValuesFormat.name().equals(defaultDocValuesFormat())) {
|
||||
builder.field(DOC_VALUES_FORMAT, docValuesFormat.name());
|
||||
}
|
||||
} else if (includeDefaults) {
|
||||
String format = defaultDocValuesFormat();
|
||||
if (format == null) {
|
||||
format = DocValuesFormatService.DEFAULT_FORMAT;
|
||||
}
|
||||
builder.field(DOC_VALUES_FORMAT, format);
|
||||
}
|
||||
|
||||
if (customFieldDataSettings != null) {
|
||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||
} else if (includeDefaults) {
|
||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
||||
}
|
||||
|
||||
builder.endObject();
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.elasticsearch.common.Strings;
|
|||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.codec.docvaluesformat.DocValuesFormatProvider;
|
||||
import org.elasticsearch.index.codec.docvaluesformat.DocValuesFormatService;
|
||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||
import org.elasticsearch.index.mapper.*;
|
||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||
|
@ -169,11 +170,25 @@ public class VersionFieldMapper extends AbstractFieldMapper<Long> implements Int
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
if (docValuesFormat == null || docValuesFormat.name().equals(defaultDocValuesFormat())) {
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
if (!includeDefaults && (docValuesFormat == null || docValuesFormat.name().equals(defaultDocValuesFormat()))) {
|
||||
return builder;
|
||||
}
|
||||
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
if (docValuesFormat != null) {
|
||||
if (includeDefaults || !docValuesFormat.name().equals(defaultDocValuesFormat())) {
|
||||
builder.field(DOC_VALUES_FORMAT, docValuesFormat.name());
|
||||
}
|
||||
} else {
|
||||
String format = defaultDocValuesFormat();
|
||||
if (format == null) {
|
||||
format = DocValuesFormatService.DEFAULT_FORMAT;
|
||||
}
|
||||
builder.field(DOC_VALUES_FORMAT, format);
|
||||
}
|
||||
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
|
|
@ -321,17 +321,21 @@ public class IpFieldMapper extends NumberFieldMapper<Long> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (precisionStep != Defaults.PRECISION_STEP) {
|
||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
|
||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
|
||||
builder.field("precision_step", precisionStep);
|
||||
}
|
||||
if (nullValue != null) {
|
||||
if (includeDefaults || nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
||||
if (includeInAll != null) {
|
||||
builder.field("include_in_all", includeInAll);
|
||||
} else if (includeDefaults) {
|
||||
builder.field("include_in_all", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class NumericIpAnalyzer extends NumericAnalyzer<NumericIpTokenizer> {
|
||||
|
|
|
@ -324,6 +324,7 @@ public class MultiFieldMapper implements Mapper, AllFieldMapper.IncludeInAll {
|
|||
builder.field("path", pathType.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
|
||||
builder.startObject("fields");
|
||||
if (defaultMapper != null) {
|
||||
defaultMapper.toXContent(builder, params);
|
||||
|
|
|
@ -21,7 +21,8 @@ package org.elasticsearch.index.similarity;
|
|||
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.apache.lucene.search.similarities.*;
|
||||
import org.apache.lucene.search.similarities.BM25Similarity;
|
||||
import org.apache.lucene.search.similarities.DefaultSimilarity;
|
||||
import org.elasticsearch.common.collect.MapBuilder;
|
||||
|
||||
/**
|
||||
|
@ -33,7 +34,8 @@ public class Similarities {
|
|||
|
||||
static {
|
||||
MapBuilder<String, PreBuiltSimilarityProvider.Factory> similarities = MapBuilder.newMapBuilder();
|
||||
similarities.put("default", new PreBuiltSimilarityProvider.Factory("default", new DefaultSimilarity()));
|
||||
similarities.put(SimilarityLookupService.DEFAULT_SIMILARITY,
|
||||
new PreBuiltSimilarityProvider.Factory(SimilarityLookupService.DEFAULT_SIMILARITY, new DefaultSimilarity()));
|
||||
similarities.put("BM25", new PreBuiltSimilarityProvider.Factory("BM25", new BM25Similarity()));
|
||||
|
||||
PRE_BUILT_SIMILARITIES = similarities.immutableMap();
|
||||
|
|
|
@ -32,16 +32,18 @@ import java.util.Map;
|
|||
|
||||
/**
|
||||
* Service for looking up configured {@link SimilarityProvider} implementations by name.
|
||||
*
|
||||
* <p/>
|
||||
* The service instantiates the Providers through their Factories using configuration
|
||||
* values found with the {@link SimilarityModule#SIMILARITY_SETTINGS_PREFIX} prefix.
|
||||
*/
|
||||
public class SimilarityLookupService extends AbstractIndexComponent {
|
||||
|
||||
public final static String DEFAULT_SIMILARITY = "default";
|
||||
|
||||
private final ImmutableMap<String, SimilarityProvider> similarities;
|
||||
|
||||
public SimilarityLookupService(Index index, Settings indexSettings) {
|
||||
this (index, indexSettings, ImmutableMap.<String, SimilarityProvider.Factory>of());
|
||||
this(index, indexSettings, ImmutableMap.<String, SimilarityProvider.Factory>of());
|
||||
}
|
||||
|
||||
@Inject
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.index.similarity;
|
|||
import org.apache.lucene.search.similarities.PerFieldSimilarityWrapper;
|
||||
import org.apache.lucene.search.similarities.Similarity;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.inject.name.Named;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.AbstractIndexComponent;
|
||||
|
@ -46,7 +45,7 @@ public class SimilarityService extends AbstractIndexComponent {
|
|||
}
|
||||
|
||||
public SimilarityService(Index index, Settings settings) {
|
||||
this (index, settings, new SimilarityLookupService(index, settings), null);
|
||||
this(index, settings, new SimilarityLookupService(index, settings), null);
|
||||
}
|
||||
|
||||
@Inject
|
||||
|
@ -56,7 +55,7 @@ public class SimilarityService extends AbstractIndexComponent {
|
|||
this.similarityLookupService = similarityLookupService;
|
||||
this.mapperService = mapperService;
|
||||
|
||||
Similarity defaultSimilarity = similarityLookupService.similarity("default").get();
|
||||
Similarity defaultSimilarity = similarityLookupService.similarity(SimilarityLookupService.DEFAULT_SIMILARITY).get();
|
||||
// Expert users can configure the base type as being different to default, but out-of-box we use default.
|
||||
Similarity baseSimilarity = (similarityLookupService.similarity("base") != null) ? similarityLookupService.similarity("base").get() :
|
||||
defaultSimilarity;
|
||||
|
|
|
@ -50,6 +50,7 @@ import org.elasticsearch.rest.action.admin.indices.exists.types.RestTypesExistsA
|
|||
import org.elasticsearch.rest.action.admin.indices.flush.RestFlushAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.gateway.snapshot.RestGatewaySnapshotAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.mapping.delete.RestDeleteMappingAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.mapping.get.RestGetFieldMappingAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.mapping.get.RestGetMappingAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.mapping.put.RestPutMappingAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.open.RestOpenIndexAction;
|
||||
|
@ -161,6 +162,7 @@ public class RestActionModule extends AbstractModule {
|
|||
bind(RestPutMappingAction.class).asEagerSingleton();
|
||||
bind(RestDeleteMappingAction.class).asEagerSingleton();
|
||||
bind(RestGetMappingAction.class).asEagerSingleton();
|
||||
bind(RestGetFieldMappingAction.class).asEagerSingleton();
|
||||
|
||||
bind(RestGatewaySnapshotAction.class).asEagerSingleton();
|
||||
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch licenses this
|
||||
* file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.rest.action.admin.indices.mapping.get;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.rest.*;
|
||||
import org.elasticsearch.rest.action.support.RestXContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||
import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
|
||||
import static org.elasticsearch.rest.RestStatus.OK;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class RestGetFieldMappingAction extends BaseRestHandler {
|
||||
|
||||
@Inject
|
||||
public RestGetFieldMappingAction(Settings settings, Client client, RestController controller) {
|
||||
super(settings, client);
|
||||
controller.registerHandler(GET, "/_mapping/field/{fields}", this);
|
||||
controller.registerHandler(GET, "/{index}/_mapping/field/{fields}", this);
|
||||
controller.registerHandler(GET, "/{index}/{type}/_mapping/field/{fields}", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRequest(final RestRequest request, final RestChannel channel) {
|
||||
final String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
|
||||
final String[] types = Strings.splitStringByCommaToArray(request.param("type"));
|
||||
boolean local = request.paramAsBooleanOptional("local", false);
|
||||
final String[] fields = Strings.splitStringByCommaToArray(request.param("fields"));
|
||||
|
||||
GetFieldMappingsRequest getMappingsRequest = new GetFieldMappingsRequest();
|
||||
getMappingsRequest.indices(indices).types(types).local(local).fields(fields).includeDefaults(request.paramAsBoolean("include_defaults", false));
|
||||
client.admin().indices().getFieldMappings(getMappingsRequest, new ActionListener<GetFieldMappingsResponse>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onResponse(GetFieldMappingsResponse response) {
|
||||
try {
|
||||
XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
|
||||
builder.startObject();
|
||||
|
||||
ImmutableMap<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> mappingsByIndex = response.mappings();
|
||||
RestStatus status = OK;
|
||||
if (mappingsByIndex.isEmpty() && fields.length > 0) {
|
||||
status = NOT_FOUND;
|
||||
}
|
||||
response.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
builder.endObject();
|
||||
channel.sendResponse(new XContentRestResponse(request, status, builder));
|
||||
} catch (Throwable e) {
|
||||
onFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
try {
|
||||
channel.sendResponse(new XContentThrowableRestResponse(request, e));
|
||||
} catch (IOException e1) {
|
||||
logger.error("Failed to send failure response", e1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -25,7 +25,6 @@ import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
|||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
@ -60,7 +59,6 @@ public class RestGetMappingAction extends BaseRestHandler {
|
|||
final String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
|
||||
final String[] types = Strings.splitStringByCommaToArray(request.param("type"));
|
||||
boolean local = request.paramAsBooleanOptional("local", false);
|
||||
|
||||
GetMappingsRequest getMappingsRequest = new GetMappingsRequest();
|
||||
getMappingsRequest.indices(indices).types(types).local(local);
|
||||
client.admin().indices().getMappings(getMappingsRequest, new ActionListener<GetMappingsResponse>() {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.index.mapper.routing;
|
||||
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
|
@ -31,7 +32,6 @@ import org.junit.Test;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
/**
|
||||
|
@ -78,7 +78,7 @@ public class RoutingTypeMapperTests extends ElasticsearchTestCase {
|
|||
DocumentMapper enabledMapper = MapperTestUtils.newParser().parse(enabledMapping);
|
||||
|
||||
XContentBuilder builder = JsonXContent.contentBuilder().startObject();
|
||||
enabledMapper.routingFieldMapper().toXContent(builder, null).endObject();
|
||||
enabledMapper.routingFieldMapper().toXContent(builder, ToXContent.EMPTY_PARAMS).endObject();
|
||||
builder.close();
|
||||
Map<String, Object> serializedMap = JsonXContent.jsonXContent.createParser(builder.bytes()).mapAndClose();
|
||||
assertThat(serializedMap, hasKey("_routing"));
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.index.mapper.timestamp;
|
||||
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
|
@ -34,7 +35,6 @@ import org.junit.Test;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
/**
|
||||
|
@ -128,7 +128,7 @@ public class TimestampMappingTests extends ElasticsearchTestCase {
|
|||
DocumentMapper mapper = MapperTestUtils.newParser().parse(mapping);
|
||||
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder().startObject();
|
||||
mapper.timestampFieldMapper().toXContent(builder, null);
|
||||
mapper.timestampFieldMapper().toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
builder.endObject();
|
||||
|
||||
assertThat(builder.string(), is(String.format(Locale.ROOT, "{\"%s\":{}}", TimestampFieldMapper.NAME)));
|
||||
|
@ -142,7 +142,7 @@ public class TimestampMappingTests extends ElasticsearchTestCase {
|
|||
DocumentMapper enabledMapper = MapperTestUtils.newParser().parse(enabledMapping);
|
||||
|
||||
XContentBuilder builder = JsonXContent.contentBuilder().startObject();
|
||||
enabledMapper.timestampFieldMapper().toXContent(builder, null).endObject();
|
||||
enabledMapper.timestampFieldMapper().toXContent(builder, ToXContent.EMPTY_PARAMS).endObject();
|
||||
builder.close();
|
||||
Map<String, Object> serializedMap = JsonXContent.jsonXContent.createParser(builder.bytes()).mapAndClose();
|
||||
assertThat(serializedMap, hasKey("_timestamp"));
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch licenses this
|
||||
* file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.indices.mapping;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.test.AbstractIntegrationTest;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class SimpleGetFieldMappingsTests extends AbstractIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void getMappingsWhereThereAreNone() {
|
||||
createIndex("index");
|
||||
GetFieldMappingsResponse response = client().admin().indices().prepareGetFieldMappings().get();
|
||||
assertThat(response.mappings().size(), equalTo(0));
|
||||
|
||||
assertThat(response.fieldMappings("index", "type", "field"), Matchers.nullValue());
|
||||
}
|
||||
|
||||
private XContentBuilder getMappingForType(String type) throws IOException {
|
||||
return jsonBuilder().startObject().startObject(type).startObject("properties")
|
||||
.startObject("field1").field("type", "string").endObject()
|
||||
.startObject("obj").startObject("properties").startObject("subfield").field("type", "string").field("index", "not_analyzed").endObject().endObject().endObject()
|
||||
.endObject().endObject().endObject();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleGetFieldMappings() throws Exception {
|
||||
|
||||
|
||||
assertTrue(client().admin().indices().prepareCreate("indexa")
|
||||
.addMapping("typeA", getMappingForType("typeA"))
|
||||
.addMapping("typeB", getMappingForType("typeB"))
|
||||
.get().isAcknowledged());
|
||||
assertTrue(client().admin().indices().prepareCreate("indexb")
|
||||
.addMapping("typeA", getMappingForType("typeA"))
|
||||
.addMapping("typeB", getMappingForType("typeB"))
|
||||
.get().isAcknowledged());
|
||||
|
||||
// Get mappings by full name
|
||||
GetFieldMappingsResponse response = client().admin().indices().prepareGetFieldMappings("indexa").setTypes("typeA").setFields("field1", "obj.subfield").get();
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "field1").fullName(), equalTo("field1"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "field1").sourceAsMap(), hasKey("field1"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "obj.subfield").fullName(), equalTo("obj.subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "obj.subfield").sourceAsMap(), hasKey("subfield"));
|
||||
assertThat(response.mappings().get("indexa"), not(hasKey("typeB")));
|
||||
assertThat(response.fieldMappings("indexa", "typeB", "field1"), nullValue());
|
||||
assertThat(response.mappings(), not(hasKey("indexb")));
|
||||
assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue());
|
||||
|
||||
// Get mappings by name
|
||||
response = client().admin().indices().prepareGetFieldMappings("indexa").setTypes("typeA").setFields("field1", "subfield").get();
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "field1").fullName(), equalTo("field1"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "field1").sourceAsMap(), hasKey("field1"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "subfield").fullName(), equalTo("obj.subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "subfield").sourceAsMap(), hasKey("subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeB", "field1"), nullValue());
|
||||
assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue());
|
||||
|
||||
// get mappings by name across multiple indices
|
||||
response = client().admin().indices().prepareGetFieldMappings().setTypes("typeA").setFields("subfield").get();
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "subfield").fullName(), equalTo("obj.subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "subfield").sourceAsMap(), hasKey("subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeB", "subfield"), nullValue());
|
||||
assertThat(response.fieldMappings("indexb", "typeA", "subfield").fullName(), equalTo("obj.subfield"));
|
||||
assertThat(response.fieldMappings("indexb", "typeA", "subfield").sourceAsMap(), hasKey("subfield"));
|
||||
assertThat(response.fieldMappings("indexb", "typeB", "subfield"), nullValue());
|
||||
|
||||
// get mappings by name across multiple types
|
||||
response = client().admin().indices().prepareGetFieldMappings("indexa").setFields("subfield").get();
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "subfield").fullName(), equalTo("obj.subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "subfield").sourceAsMap(), hasKey("subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "field1"), nullValue());
|
||||
assertThat(response.fieldMappings("indexa", "typeB", "subfield").fullName(), equalTo("obj.subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeB", "subfield").sourceAsMap(), hasKey("subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeB", "field1"), nullValue());
|
||||
assertThat(response.fieldMappings("indexb", "typeA", "subfield"), nullValue());
|
||||
assertThat(response.fieldMappings("indexb", "typeA", "field1"), nullValue());
|
||||
assertThat(response.fieldMappings("indexb", "typeB", "subfield"), nullValue());
|
||||
assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue());
|
||||
|
||||
// get mappings by name across multiple types & indices
|
||||
response = client().admin().indices().prepareGetFieldMappings().setFields("subfield").get();
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "subfield").fullName(), equalTo("obj.subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "subfield").sourceAsMap(), hasKey("subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeA", "field1"), nullValue());
|
||||
assertThat(response.fieldMappings("indexa", "typeB", "subfield").fullName(), equalTo("obj.subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeB", "subfield").sourceAsMap(), hasKey("subfield"));
|
||||
assertThat(response.fieldMappings("indexa", "typeB", "field1"), nullValue());
|
||||
assertThat(response.fieldMappings("indexb", "typeA", "subfield").fullName(), equalTo("obj.subfield"));
|
||||
assertThat(response.fieldMappings("indexb", "typeA", "subfield").sourceAsMap(), hasKey("subfield"));
|
||||
assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue());
|
||||
assertThat(response.fieldMappings("indexb", "typeB", "subfield").fullName(), equalTo("obj.subfield"));
|
||||
assertThat(response.fieldMappings("indexb", "typeB", "subfield").sourceAsMap(), hasKey("subfield"));
|
||||
assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue());
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void simpleGetFieldMappingsWithDefaults() throws Exception {
|
||||
client().admin().indices().prepareCreate("test")
|
||||
.addMapping("type", getMappingForType("type")).get();
|
||||
|
||||
client().prepareIndex("test", "type", "1").setSource("num", 1).get();
|
||||
|
||||
awaitBusy(new Predicate<Object>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable java.lang.Object input) {
|
||||
GetFieldMappingsResponse response = client().admin().indices().prepareGetFieldMappings().setFields("num").get();
|
||||
return response.fieldMappings("test", "type", "num") != null;
|
||||
}
|
||||
});
|
||||
|
||||
GetFieldMappingsResponse response = client().admin().indices().prepareGetFieldMappings().setFields("num", "field1", "subfield").includeDefaults(true).get();
|
||||
|
||||
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "num").sourceAsMap().get("num"), hasEntry("index", (Object) "not_analyzed"));
|
||||
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "num").sourceAsMap().get("num"), hasEntry("type", (Object) "long"));
|
||||
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "field1").sourceAsMap().get("field1"), hasEntry("index", (Object) "analyzed"));
|
||||
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "field1").sourceAsMap().get("field1"), hasEntry("type", (Object) "string"));
|
||||
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "subfield").sourceAsMap().get("subfield"), hasEntry("index", (Object) "not_analyzed"));
|
||||
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "subfield").sourceAsMap().get("subfield"), hasEntry("type", (Object) "string"));
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue