Skip to content

Commit

Permalink
Add a GetFieldMapping API
Browse files Browse the repository at this point in the history
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 elastic#3941
  • Loading branch information
bleskes committed Oct 29, 2013
1 parent 5639002 commit ceb779e
Show file tree
Hide file tree
Showing 54 changed files with 1,372 additions and 199 deletions.
4 changes: 4 additions & 0 deletions docs/reference/indices.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ and warmers.
== Mapping management:

* <<indices-put-mapping>>
* <<indices-get-mapping>>
* <<indices-get-field-mapping>>
* <<indices-delete-mapping>>
* <<indices-types-exists>>

Expand Down Expand Up @@ -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[]
Expand Down
137 changes: 137 additions & 0 deletions docs/reference/indices/get-field-mapping.asciidoc
Original file line number Diff line number Diff line change
@@ -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.
10 changes: 5 additions & 5 deletions docs/reference/indices/get-mapping.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -21,17 +21,17 @@ 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
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'
--------------------------------------------------
3 changes: 3 additions & 0 deletions src/main/java/org/elasticsearch/action/ActionModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@
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;
Expand Down Expand Up @@ -200,6 +202,7 @@ protected void configure() {
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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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 comments on commit ceb779e

Please sign in to comment.