| package org.apache.usergrid.persistence.index.impl;/* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF 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. |
| */ |
| |
| |
| import java.io.IOException; |
| import java.util.UUID; |
| |
| import org.apache.usergrid.persistence.core.scope.ApplicationScope; |
| import org.apache.usergrid.persistence.index.IndexFig; |
| import org.apache.usergrid.persistence.index.IndexIdentifier; |
| import org.apache.usergrid.persistence.index.IndexScope; |
| import org.apache.usergrid.persistence.model.entity.Entity; |
| import org.apache.usergrid.persistence.model.entity.Id; |
| import org.elasticsearch.common.xcontent.XContentBuilder; |
| |
| |
| public class IndexingUtils { |
| |
| public static final String STRING_PREFIX = "su_"; |
| public static final String ANALYZED_STRING_PREFIX = "sa_"; |
| public static final String GEO_PREFIX = "go_"; |
| public static final String NUMBER_PREFIX = "nu_"; |
| public static final String BOOLEAN_PREFIX = "bu_"; |
| |
| public static final String SPLITTER = "\\__"; |
| |
| // These are not allowed in document type names: _ . , | # |
| public static final String SEPARATOR = "__"; |
| |
| |
| // |
| // Reserved UG fields. |
| // |
| |
| public static final String ENTITY_CONTEXT_FIELDNAME = "ug_context"; |
| |
| public static final String ENTITYID_ID_FIELDNAME = "ug_entityId"; |
| |
| public static final String ENTITY_VERSION_FIELDNAME = "ug_entityVersion"; |
| |
| |
| /** |
| * Create our sub scope. This is the ownerUUID + type |
| * @param scope |
| * @return |
| */ |
| public static String createContextName( IndexScope scope ) { |
| StringBuilder sb = new StringBuilder(); |
| idString(sb, scope.getOwner()); |
| sb.append( SEPARATOR ); |
| sb.append( scope.getName() ); |
| return sb.toString(); |
| } |
| |
| |
| /** |
| * Append the id to the string |
| * @param builder |
| * @param id |
| */ |
| public static final void idString(final StringBuilder builder, final Id id){ |
| builder.append( id.getUuid() ).append( SEPARATOR ) |
| .append(id.getType()); |
| } |
| |
| |
| /** |
| * Turn the id into a string |
| * @param id |
| * @return |
| */ |
| public static final String idString(final Id id){ |
| final StringBuilder sb = new StringBuilder( ); |
| idString(sb, id); |
| return sb.toString(); |
| } |
| |
| |
| /** |
| * Create the facilities to retrieve an index name and alias name |
| * @param fig |
| * @param applicationScope |
| * @return |
| */ |
| public static IndexIdentifier createIndexIdentifier(IndexFig fig, ApplicationScope applicationScope) { |
| return new IndexIdentifier(fig,applicationScope); |
| } |
| |
| |
| |
| |
| |
| /** |
| * Create the index doc from the given entity |
| * @param entity |
| * @return |
| */ |
| public static String createIndexDocId(final Entity entity, final String context) { |
| return createIndexDocId(entity.getId(), entity.getVersion(), context); |
| } |
| |
| |
| /** |
| * Create the doc Id. This is the entitie's type + uuid + version |
| * @param entityId |
| * @param version |
| * @para context The context it's indexed in |
| * @return |
| */ |
| public static String createIndexDocId(final Id entityId, final UUID version, final String context) { |
| StringBuilder sb = new StringBuilder(); |
| idString(sb, entityId); |
| sb.append( SEPARATOR ); |
| sb.append( version.toString() ).append( SEPARATOR ); |
| sb.append( context); |
| return sb.toString(); |
| } |
| |
| |
| /** |
| * Build mappings for data to be indexed. Setup String fields as not_analyzed and analyzed, |
| * where the analyzed field is named {name}_ug_analyzed |
| * |
| * @param builder Add JSON object to this builder. |
| * @param type ElasticSearch type of entity. |
| * |
| * @return Content builder with JSON for mapping. |
| * |
| * @throws java.io.IOException On JSON generation error. |
| */ |
| public static XContentBuilder createDoubleStringIndexMapping( |
| XContentBuilder builder, String type ) throws IOException { |
| |
| builder = builder |
| |
| .startObject() |
| |
| /** add routing "_routing":{ "required":false, "path":"ug_entityId" **/ |
| .startObject("_routing").field("required",true).field("path",ENTITYID_ID_FIELDNAME).endObject() |
| .startArray("dynamic_templates") |
| // we need most specific mappings first since it's a stop on match algorithm |
| |
| .startObject() |
| |
| .startObject( "entity_id_template" ) |
| .field( "match", IndexingUtils.ENTITYID_ID_FIELDNAME ) |
| .field( "match_mapping_type", "string" ) |
| .startObject( "mapping" ).field( "type", "string" ) |
| .field( "index", "not_analyzed" ) |
| .endObject() |
| .endObject() |
| .endObject() |
| |
| .startObject() |
| .startObject( "entity_context_template" ) |
| .field( "match", IndexingUtils.ENTITY_CONTEXT_FIELDNAME ) |
| .field( "match_mapping_type", "string" ) |
| .startObject( "mapping" ) |
| .field( "type", "string" ) |
| .field( "index", "not_analyzed" ).endObject() |
| .endObject() |
| .endObject() |
| |
| .startObject() |
| .startObject( "entity_version_template" ) |
| .field( "match", IndexingUtils.ENTITY_VERSION_FIELDNAME ) |
| .field( "match_mapping_type", "string" ) |
| .startObject( "mapping" ).field( "type", "long" ) |
| .endObject() |
| .endObject() |
| .endObject() |
| |
| // any string with field name that starts with sa_ gets analyzed |
| .startObject() |
| .startObject( "template_1" ) |
| .field( "match", ANALYZED_STRING_PREFIX + "*" ) |
| .field( "match_mapping_type", "string" ).startObject( "mapping" ) |
| .field( "type", "string" ) |
| .field( "index", "analyzed" ) |
| .endObject() |
| .endObject() |
| |
| .endObject() |
| |
| // all other strings are not analyzed |
| .startObject() |
| .startObject( "template_2" ) |
| //todo, should be string prefix, remove 2 field mapping |
| .field( "match", "*" ) |
| .field( "match_mapping_type", "string" ) |
| .startObject( "mapping" ) |
| .field( "type", "string" ) |
| .field( "index", "not_analyzed" ) |
| .endObject() |
| .endObject() |
| .endObject() |
| |
| // fields names starting with go_ get geo-indexed |
| .startObject() |
| .startObject( "template_3" ) |
| .field( "match", GEO_PREFIX + "location" ) |
| .startObject( "mapping" ) |
| .field( "type", "geo_point" ) |
| .endObject() |
| .endObject() |
| .endObject() |
| |
| .endArray() |
| |
| .endObject(); |
| |
| return builder; |
| } |
| |
| |
| |
| } |