blob: ffd98e9dc89d273fed3f7b99dc4af7c1bd1300ee [file] [log] [blame]
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;
}
}