This is an automated email from the ASF dual-hosted git repository.
amestry pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/master by this push:
new 2223c82 ATLAS-3370: Aggregation Metrics with quick search.
Modifications to DSL Query Processor and Basic Search.
2223c82 is described below
commit 2223c82c60b791ae2b66f6d78e1289ebe519cfa4
Author: Ashutosh Mestry <[email protected]>
AuthorDate: Fri Aug 16 09:08:07 2019 -0700
ATLAS-3370: Aggregation Metrics with quick search. Modifications to DSL
Query Processor and Basic Search.
---
addons/models/0000-Area0/0010-base_model.json | 820 +++++++++++----------
.../repository/graphdb/AtlasGraphManagement.java | 5 +-
.../repository/graphdb/janus/AtlasJanusGraph.java | 12 +-
.../graphdb/janus/AtlasJanusGraphManagement.java | 31 +-
.../graphdb/janus/AbstractGraphDatabaseTest.java | 2 +-
.../apache/atlas/model/typedef/AtlasStructDef.java | 53 +-
.../org/apache/atlas/type/AtlasStructType.java | 25 +-
.../v1/model/typedef/AttributeDefinition.java | 49 +-
.../apache/atlas/discovery/SearchProcessor.java | 5 +-
.../org/apache/atlas/query/GremlinClauseList.java | 8 -
.../apache/atlas/query/GremlinQueryComposer.java | 56 +-
.../org/apache/atlas/query/IdentifierHelper.java | 24 +-
.../main/java/org/apache/atlas/query/Lookup.java | 2 +
.../apache/atlas/query/RegistryBasedLookup.java | 11 +
.../apache/atlas/query/SelectClauseComposer.java | 14 +-
.../repository/converters/TypeConverterUtil.java | 16 +-
.../repository/graph/GraphBackedSearchIndexer.java | 83 ++-
.../repository/patches/UniqueAttributePatch.java | 9 +-
.../bootstrap/AtlasTypeDefStoreInitializer.java | 13 +
.../store/graph/v2/AtlasStructDefStoreV2.java | 8 +-
.../atlas/query/GremlinQueryComposerTest.java | 21 +-
.../search-parameters/combination-filters.json | 4 +-
22 files changed, 720 insertions(+), 551 deletions(-)
diff --git a/addons/models/0000-Area0/0010-base_model.json
b/addons/models/0000-Area0/0010-base_model.json
index 1c80711..2f5fdaf 100644
--- a/addons/models/0000-Area0/0010-base_model.json
+++ b/addons/models/0000-Area0/0010-base_model.json
@@ -1,442 +1,444 @@
{
- "enumDefs": [],
- "structDefs": [],
- "classificationDefs": [],
- "entityDefs": [
- {
- "name": "Referenceable",
- "superTypes": [],
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "attributeDefs": [
- {
- "name": "qualifiedName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": true
- }
- ]
+ "enumDefs": [],
+ "structDefs": [],
+ "classificationDefs": [],
+ "entityDefs": [
+ {
+ "name": "Referenceable",
+ "superTypes": [],
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "attributeDefs": [
+ {
+ "name": "qualifiedName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": true
+ }
+ ]
+ },
+ {
+ "name": "__internal",
+ "superTypes": [],
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "attributeDefs": []
+ },
+ {
+ "name": "Asset",
+ "superTypes": [
+ "Referenceable"
+ ],
+ "serviceType": "atlas_core",
+ "typeVersion": "1.1",
+ "attributeDefs": [
+ {
+ "name": "name",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false,
+ "indexType": "STRING"
},
{
- "name": "__internal",
- "superTypes": [],
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "attributeDefs": []
+ "name": "description",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
},
{
- "name": "Asset",
- "superTypes": [
- "Referenceable"
- ],
- "serviceType": "atlas_core",
- "typeVersion": "1.1",
- "attributeDefs": [
- {
- "name": "name",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "description",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- },
- {
- "name": "owner",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": true,
- "isUnique": false
- }
- ]
+ "name": "owner",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": true,
+ "isUnique": false,
+ "indexType": "STRING"
+ }
+ ]
+ },
+ {
+ "name": "ddl",
+ "superTypes": [
+ "Referenceable"
+ ],
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "attributeDefs": [
+ {
+ "name": "queryText",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false
},
{
- "name": "ddl",
- "superTypes": [
- "Referenceable"
- ],
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "attributeDefs": [
- {
- "name": "queryText",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "execTime",
- "typeName": "date",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "userName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "serviceType",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": false
- }
- ]
+ "name": "execTime",
+ "typeName": "date",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": false,
+ "isUnique": false
},
{
- "name": "DataSet",
- "superTypes": [
- "Asset"
- ],
- "serviceType": "atlas_core",
- "typeVersion": "1.1",
- "attributeDefs": []
+ "name": "userName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false
},
{
- "name": "Infrastructure",
- "description":"Infrastructure can be IT infrastructure, which
contains hosts and servers. Infrastructure might not be IT orientated, such as
'Car' for IoT applications.",
- "superTypes": [
- "Asset"
- ],
- "serviceType": "atlas_core",
- "typeVersion": "1.1",
- "attributeDefs": []
+ "name": "serviceType",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false
+ }
+ ]
+ },
+ {
+ "name": "DataSet",
+ "superTypes": [
+ "Asset"
+ ],
+ "serviceType": "atlas_core",
+ "typeVersion": "1.1",
+ "attributeDefs": []
+ },
+ {
+ "name": "Infrastructure",
+ "description": "Infrastructure can be IT infrastructure, which contains
hosts and servers. Infrastructure might not be IT orientated, such as 'Car' for
IoT applications.",
+ "superTypes": [
+ "Asset"
+ ],
+ "serviceType": "atlas_core",
+ "typeVersion": "1.1",
+ "attributeDefs": []
+ },
+ {
+ "name": "Process",
+ "superTypes": [
+ "Asset"
+ ],
+ "serviceType": "atlas_core",
+ "typeVersion": "1.1",
+ "attributeDefs": [
+ {
+ "name": "inputs",
+ "typeName": "array<DataSet>",
+ "cardinality": "SET",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
},
{
- "name": "Process",
- "superTypes": [
- "Asset"
- ],
- "serviceType": "atlas_core",
- "typeVersion": "1.1",
- "attributeDefs": [
- {
- "name": "inputs",
- "typeName": "array<DataSet>",
- "cardinality": "SET",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- },
- {
- "name": "outputs",
- "typeName": "array<DataSet>",
- "cardinality": "SET",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- }
- ]
+ "name": "outputs",
+ "typeName": "array<DataSet>",
+ "cardinality": "SET",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
+ }
+ ]
+ },
+ {
+ "name": "AtlasServer",
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "superTypes": [
+ ],
+ "attributeDefs": [
+ {
+ "name": "name",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false
},
{
- "name": "AtlasServer",
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "superTypes": [
- ],
- "attributeDefs": [
- {
- "name": "name",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "displayName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "fullName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": true
- },
- {
- "name": "urls",
- "typeName": "array<string>",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- },
- {
- "name": "additionalInfo",
- "typeName": "map<string,string>",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- }
- ]
+ "name": "displayName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false
},
{
- "name": "__AtlasUserProfile",
- "superTypes": [
- "__internal"
- ],
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "attributeDefs": [
- {
- "name": "name",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": true
- },
- {
- "name": "fullName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- },
- {
- "name": "savedSearches",
- "typeName": "array<__AtlasUserSavedSearch>",
- "cardinality": "SET",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false,
- "constraints": [
- {
- "type": "ownedRef"
- }
- ]
- }
- ]
+ "name": "fullName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": true
},
{
- "name": "__AtlasUserSavedSearch",
- "superTypes": [
- "__internal"
- ],
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "attributeDefs": [
- {
- "name": "name",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "ownerName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "searchType",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "uniqueName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": true
- },
- {
- "name": "searchParameters",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "uiParameters",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- }
- ]
+ "name": "urls",
+ "typeName": "array<string>",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
},
{
- "name": "__ExportImportAuditEntry",
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "superTypes": [
- "__internal"
- ],
- "attributeDefs": [
- {
- "name": "userName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- },
- {
- "name": "operation",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "sourceServerName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": true,
- "isUnique": false
- },
- {
- "name": "targetServerName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": true,
- "isUnique": false
- },
- {
- "name": "operationParams",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": true,
- "isUnique": false
- },
- {
- "name": "operationStartTime",
- "typeName": "long",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "operationEndTime",
- "typeName": "long",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": true,
- "isUnique": false
- },
+ "name": "additionalInfo",
+ "typeName": "map<string,string>",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
+ }
+ ]
+ },
+ {
+ "name": "__AtlasUserProfile",
+ "superTypes": [
+ "__internal"
+ ],
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "attributeDefs": [
+ {
+ "name": "name",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": true
+ },
+ {
+ "name": "fullName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
+ },
+ {
+ "name": "savedSearches",
+ "typeName": "array<__AtlasUserSavedSearch>",
+ "cardinality": "SET",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false,
+ "constraints": [
{
- "name": "resultSummary",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
+ "type": "ownedRef"
}
]
+ }
+ ]
+ },
+ {
+ "name": "__AtlasUserSavedSearch",
+ "superTypes": [
+ "__internal"
+ ],
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "attributeDefs": [
+ {
+ "name": "name",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": false,
+ "isUnique": false
},
{
- "name": "ProcessExecution",
- "superTypes": [
- "Asset"
- ],
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "attributeDefs": []
+ "name": "ownerName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": false,
+ "isUnique": false
+ },
+ {
+ "name": "searchType",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false
+ },
+ {
+ "name": "uniqueName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": true
+ },
+ {
+ "name": "searchParameters",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": false,
+ "isUnique": false
+ },
+ {
+ "name": "uiParameters",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
}
- ],
- "relationshipDefs": [
- {
- "name": "dataset_process_inputs",
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "relationshipCategory": "AGGREGATION",
- "endDef1": {
- "type": "Process",
- "name": "inputs",
- "isContainer": true,
- "cardinality": "SET",
- "isLegacyAttribute": true
- },
- "endDef2": {
- "type": "DataSet",
- "name": "inputToProcesses",
- "isContainer": false,
- "cardinality": "SET"
- },
- "propagateTags": "TWO_TO_ONE"
+ ]
+ },
+ {
+ "name": "__ExportImportAuditEntry",
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "superTypes": [
+ "__internal"
+ ],
+ "attributeDefs": [
+ {
+ "name": "userName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
+ },
+ {
+ "name": "operation",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false
+ },
+ {
+ "name": "sourceServerName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": true,
+ "isUnique": false
+ },
+ {
+ "name": "targetServerName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": true,
+ "isUnique": false
+ },
+ {
+ "name": "operationParams",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": true,
+ "isUnique": false
+ },
+ {
+ "name": "operationStartTime",
+ "typeName": "long",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false
},
{
- "name": "process_dataset_outputs",
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "relationshipCategory": "AGGREGATION",
- "endDef1": {
- "type": "Process",
- "name": "outputs",
- "isContainer": true,
- "cardinality": "SET",
- "isLegacyAttribute": true
- },
- "endDef2": {
- "type": "DataSet",
- "name": "outputFromProcesses",
- "isContainer": false,
- "cardinality": "SET"
- },
- "propagateTags": "ONE_TO_TWO"
+ "name": "operationEndTime",
+ "typeName": "long",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": true,
+ "isUnique": false
},
{
- "name": "__AtlasUserProfile_savedsearches",
- "serviceType": "atlas_core",
- "typeVersion": "1.0",
- "relationshipCategory": "COMPOSITION",
- "endDef1": {
- "type": "__AtlasUserProfile",
- "name": "savedSearches",
- "isContainer": true,
- "cardinality": "SET",
- "isLegacyAttribute": true
- },
- "endDef2": {
- "type": "__AtlasUserSavedSearch",
- "name": "userProfile",
- "isContainer": false,
- "cardinality": "SINGLE"
- },
- "propagateTags": "NONE"
+ "name": "resultSummary",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
}
- ]
+ ]
+ },
+ {
+ "name": "ProcessExecution",
+ "superTypes": [
+ "Asset"
+ ],
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "attributeDefs": []
+ }
+ ],
+ "relationshipDefs": [
+ {
+ "name": "dataset_process_inputs",
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "relationshipCategory": "AGGREGATION",
+ "endDef1": {
+ "type": "Process",
+ "name": "inputs",
+ "isContainer": true,
+ "cardinality": "SET",
+ "isLegacyAttribute": true
+ },
+ "endDef2": {
+ "type": "DataSet",
+ "name": "inputToProcesses",
+ "isContainer": false,
+ "cardinality": "SET"
+ },
+ "propagateTags": "TWO_TO_ONE"
+ },
+ {
+ "name": "process_dataset_outputs",
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "relationshipCategory": "AGGREGATION",
+ "endDef1": {
+ "type": "Process",
+ "name": "outputs",
+ "isContainer": true,
+ "cardinality": "SET",
+ "isLegacyAttribute": true
+ },
+ "endDef2": {
+ "type": "DataSet",
+ "name": "outputFromProcesses",
+ "isContainer": false,
+ "cardinality": "SET"
+ },
+ "propagateTags": "ONE_TO_TWO"
+ },
+ {
+ "name": "__AtlasUserProfile_savedsearches",
+ "serviceType": "atlas_core",
+ "typeVersion": "1.0",
+ "relationshipCategory": "COMPOSITION",
+ "endDef1": {
+ "type": "__AtlasUserProfile",
+ "name": "savedSearches",
+ "isContainer": true,
+ "cardinality": "SET",
+ "isLegacyAttribute": true
+ },
+ "endDef2": {
+ "type": "__AtlasUserSavedSearch",
+ "name": "userProfile",
+ "isContainer": false,
+ "cardinality": "SINGLE"
+ },
+ "propagateTags": "NONE"
+ }
+ ]
}
diff --git
a/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphManagement.java
b/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphManagement.java
index 08923f8..fca7890 100644
---
a/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphManagement.java
+++
b/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphManagement.java
@@ -155,9 +155,10 @@ public interface AtlasGraphManagement {
*
* @param vertexIndex
* @param propertyKey
+ * @param isStringField
* @return the index field name used for the given property
*/
- String addMixedIndex(String vertexIndex, AtlasPropertyKey propertyKey);
+ String addMixedIndex(String vertexIndex, AtlasPropertyKey propertyKey,
boolean isStringField);
/**
* Gets the index field name for the vertex property.
@@ -165,5 +166,5 @@ public interface AtlasGraphManagement {
* @param propertyKey
* @return the encoded name for the index
*/
- String getIndexFieldName(String indexName, AtlasPropertyKey propertyKey);
+ String getIndexFieldName(String indexName, AtlasPropertyKey propertyKey,
boolean isStringField);
}
diff --git
a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraph.java
b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraph.java
index 613a714..4d581ec 100644
---
a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraph.java
+++
b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraph.java
@@ -51,6 +51,7 @@ import org.janusgraph.core.PropertyKey;
import org.janusgraph.core.SchemaViolationException;
import org.janusgraph.core.schema.JanusGraphIndex;
import org.janusgraph.core.schema.JanusGraphManagement;
+import org.janusgraph.core.schema.Mapping;
import org.janusgraph.core.schema.Parameter;
import org.janusgraph.diskstorage.BackendException;
import org.janusgraph.graphdb.database.StandardJanusGraph;
@@ -75,8 +76,9 @@ import static
org.apache.atlas.repository.graphdb.janus.AtlasJanusGraphDatabase.
*/
public class AtlasJanusGraph implements AtlasGraph<AtlasJanusVertex,
AtlasJanusEdge> {
private static final Logger LOG =
LoggerFactory.getLogger(AtlasJanusGraph.class);
+ private static final Parameter[] EMPTY_PARAMETER_ARRAY = new Parameter[0];
+
- private static final Parameter[] EMPTY_PARAMETER_ARRAY = new
Parameter[0];
private static Configuration APPLICATION_PROPERTIES = null;
private final ConvertGremlinValueFunction
GREMLIN_VALUE_CONVERSION_FUNCTION = new ConvertGremlinValueFunction();
@@ -418,10 +420,12 @@ public class AtlasJanusGraph implements
AtlasGraph<AtlasJanusVertex, AtlasJanusE
}
- String getIndexFieldName(AtlasPropertyKey propertyKey, JanusGraphIndex
graphIndex) {
+ String getIndexFieldName(AtlasPropertyKey propertyKey, JanusGraphIndex
graphIndex, Parameter ... parameters) {
PropertyKey janusKey =
AtlasJanusObjectFactory.createPropertyKey(propertyKey);
-
- return janusGraph.getIndexSerializer().getDefaultFieldName(janusKey,
EMPTY_PARAMETER_ARRAY, graphIndex.getBackingIndex());
+ if(parameters == null) {
+ parameters = EMPTY_PARAMETER_ARRAY;
+ }
+ return janusGraph.getIndexSerializer().getDefaultFieldName(janusKey,
parameters, graphIndex.getBackingIndex());
}
diff --git
a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraphManagement.java
b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraphManagement.java
index b6889c8..6ef9cb7 100644
---
a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraphManagement.java
+++
b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraphManagement.java
@@ -45,6 +45,8 @@ import java.util.Set;
* Janus implementation of AtlasGraphManagement.
*/
public class AtlasJanusGraphManagement implements AtlasGraphManagement {
+ private static final Parameter[] STRING_PARAMETER_ARRAY = new
Parameter[]{Mapping.STRING.asParameter()};
+
private static final Logger LOG =
LoggerFactory.getLogger(AtlasJanusGraphManagement.class);
private static final char[] RESERVED_CHARS = { '{', '}', '"', '$',
Token.SEPARATOR_CHAR };
@@ -145,7 +147,6 @@ public class AtlasJanusGraphManagement implements
AtlasGraphManagement {
}
PropertyKeyMaker propertyKeyBuilder =
management.makePropertyKey(propertyName).dataType(propertyClass);
-
if (cardinality != null) {
Cardinality janusCardinality =
AtlasJanusObjectFactory.createCardinality(cardinality);
propertyKeyBuilder.cardinality(janusCardinality);
@@ -192,13 +193,25 @@ public class AtlasJanusGraphManagement implements
AtlasGraphManagement {
}
@Override
- public String addMixedIndex(String indexName, AtlasPropertyKey
propertyKey) {
+ public String addMixedIndex(String indexName, AtlasPropertyKey
propertyKey, boolean isStringField) {
PropertyKey janusKey =
AtlasJanusObjectFactory.createPropertyKey(propertyKey);
JanusGraphIndex janusGraphIndex = management.getGraphIndex(indexName);
- management.addIndexKey(janusGraphIndex, janusKey);
+ if(isStringField) {
+ management.addIndexKey(janusGraphIndex, janusKey,
Mapping.STRING.asParameter());
+ LOG.debug("created a string type for {} with janueKey {}.",
propertyKey.getName(), janusKey);
+ } else {
+ management.addIndexKey(janusGraphIndex, janusKey);
+ LOG.debug("created a default type for {} with janueKey {}.",
propertyKey.getName(), janusKey);
+ }
+
+ String encodedName = "";
+ if(isStringField) {
+ encodedName = graph.getIndexFieldName(propertyKey,
janusGraphIndex, STRING_PARAMETER_ARRAY);
+ } else {
+ encodedName = graph.getIndexFieldName(propertyKey,
janusGraphIndex);
+ }
- String encodedName = graph.getIndexFieldName(propertyKey,
janusGraphIndex);
LOG.info("property '{}' is encoded to '{}'.", propertyKey.getName(),
encodedName);
@@ -206,13 +219,17 @@ public class AtlasJanusGraphManagement implements
AtlasGraphManagement {
}
@Override
- public String getIndexFieldName(String indexName, AtlasPropertyKey
propertyKey) {
+ public String getIndexFieldName(String indexName, AtlasPropertyKey
propertyKey, boolean isStringField) {
JanusGraphIndex janusGraphIndex = management.getGraphIndex(indexName);
- return graph.getIndexFieldName(propertyKey, janusGraphIndex);
+ if(isStringField) {
+ return graph.getIndexFieldName(propertyKey, janusGraphIndex,
STRING_PARAMETER_ARRAY);
+ } else {
+ return graph.getIndexFieldName(propertyKey, janusGraphIndex);
+ }
+
}
- @Override
public AtlasGraphIndex getGraphIndex(String indexName) {
JanusGraphIndex index = management.getGraphIndex(indexName);
diff --git
a/graphdb/janus/src/test/java/org/apache/atlas/repository/graphdb/janus/AbstractGraphDatabaseTest.java
b/graphdb/janus/src/test/java/org/apache/atlas/repository/graphdb/janus/AbstractGraphDatabaseTest.java
index f72b412..7d1260c 100644
---
a/graphdb/janus/src/test/java/org/apache/atlas/repository/graphdb/janus/AbstractGraphDatabaseTest.java
+++
b/graphdb/janus/src/test/java/org/apache/atlas/repository/graphdb/janus/AbstractGraphDatabaseTest.java
@@ -99,7 +99,7 @@ public abstract class AbstractGraphDatabaseTest {
AtlasPropertyKey key = management.makePropertyKey(propertyName,
propertyClass, cardinality);
try {
if (propertyClass != Integer.class) {
- management.addMixedIndex(BACKING_INDEX_NAME, key);
+ management.addMixedIndex(BACKING_INDEX_NAME, key, false);
}
} catch(Throwable t) {
//ok
diff --git
a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
index 8c1dbd7..e10965b 100644
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
@@ -259,18 +259,22 @@ public class AtlasStructDef extends AtlasBaseTypeDef
implements Serializable {
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class AtlasAttributeDef implements Serializable {
- private static final long serialVersionUID = 1L;
- public static final int DEFAULT_SEARCHWEIGHT = -1;
+ private static final long serialVersionUID = 1L;
+ public static final int DEFAULT_SEARCHWEIGHT = -1;
- public static final String SEARCH_WEIGHT_ATTR_NAME =
"searchWeight";
- public static final String ATTRDEF_OPTION_SOFT_REFERENCE =
"isSoftReference";
- private final String STRING_TRUE = "true";
+
+ public static final String SEARCH_WEIGHT_ATTR_NAME =
"searchWeight";
+ public static final String INDEX_TYPE_ATTR_NAME =
"indexType";
+ public static final String ATTRDEF_OPTION_SOFT_REFERENCE =
"isSoftReference";
+ private final String STRING_TRUE = "true";
/**
* single-valued attribute or multi-valued attribute.
*/
public enum Cardinality { SINGLE, LIST, SET }
+ public enum IndexType { DEFAULT, STRING}
+
public static final int COUNT_NOT_SET = -1;
private String name;
@@ -285,6 +289,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef
implements Serializable {
private String defaultValue;
private String description;
private int searchWeight = DEFAULT_SEARCHWEIGHT;
+ private IndexType indexType = null;
private List<AtlasConstraintDef> constraints;
private Map<String, String> options;
@@ -296,32 +301,34 @@ public class AtlasStructDef extends AtlasBaseTypeDef
implements Serializable {
}
public AtlasAttributeDef(String name, String typeName, int
searchWeight) {
- this(name, typeName, false, Cardinality.SINGLE, searchWeight);
+ this(name, typeName, false, Cardinality.SINGLE, searchWeight,
null);
}
- public AtlasAttributeDef(String name, String typeName, boolean
isOptional, Cardinality cardinality) {
- this(name, typeName, isOptional, cardinality,
DEFAULT_SEARCHWEIGHT);
+ public AtlasAttributeDef(String name, String typeName, int
searchWeight, IndexType indexType) {
+ this(name, typeName, false, Cardinality.SINGLE, searchWeight,
indexType);
}
- private AtlasAttributeDef(String name, String typeName, boolean
isOptional, Cardinality cardinality, int searchWeight) {
- this(name, typeName, isOptional, cardinality, COUNT_NOT_SET,
COUNT_NOT_SET, false, false, false, null, searchWeight);
+ public AtlasAttributeDef(String name, String typeName, boolean
isOptional, Cardinality cardinality) {
+ this(name, typeName, isOptional, cardinality,
DEFAULT_SEARCHWEIGHT, null);
}
-
+ private AtlasAttributeDef(String name, String typeName, boolean
isOptional, Cardinality cardinality, int searchWeight, IndexType indexType) {
+ this(name, typeName, isOptional, cardinality, COUNT_NOT_SET,
COUNT_NOT_SET, false, false, false, null, searchWeight, indexType);
+ }
public AtlasAttributeDef(String name, String typeName, boolean
isOptional, Cardinality cardinality,
int valuesMinCount, int valuesMaxCount,
boolean isUnique, boolean isIndexable, boolean includeInNotification,
List<AtlasConstraintDef> constraints) {
- this(name, typeName, isOptional, cardinality, valuesMinCount,
valuesMaxCount, isUnique, isIndexable, includeInNotification, constraints,
DEFAULT_SEARCHWEIGHT);
+ this(name, typeName, isOptional, cardinality, valuesMinCount,
valuesMaxCount, isUnique, isIndexable, includeInNotification, constraints,
DEFAULT_SEARCHWEIGHT, null);
}
private AtlasAttributeDef(String name, String typeName, boolean
isOptional, Cardinality cardinality,
- int valuesMinCount, int valuesMaxCount,
boolean isUnique, boolean isIndexable, boolean includeInNotification,
List<AtlasConstraintDef> constraints, int searchWeight) {
- this(name, typeName, isOptional, cardinality, valuesMinCount,
valuesMaxCount, isUnique, isIndexable, includeInNotification, null,
constraints, null, null, searchWeight);
+ int valuesMinCount, int valuesMaxCount,
boolean isUnique, boolean isIndexable, boolean includeInNotification,
List<AtlasConstraintDef> constraints, int searchWeight, IndexType indexType) {
+ this(name, typeName, isOptional, cardinality, valuesMinCount,
valuesMaxCount, isUnique, isIndexable, includeInNotification, null,
constraints, null, null, searchWeight, indexType);
}
public AtlasAttributeDef(String name, String typeName, boolean
isOptional, Cardinality cardinality,
int valuesMinCount, int valuesMaxCount,
boolean isUnique, boolean isIndexable, boolean includeInNotification, String
defaultValue,
- List<AtlasConstraintDef> constraints,
Map<String,String> options, String description, int searchWeight) {
+ List<AtlasConstraintDef> constraints,
Map<String,String> options, String description, int searchWeight, IndexType
indexType) {
setName(name);
setTypeName(typeName);
setIsOptional(isOptional);
@@ -336,6 +343,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef
implements Serializable {
setOptions(options);
setDescription(description);
setSearchWeight(searchWeight);
+ setIndexType(indexType);
}
public AtlasAttributeDef(AtlasAttributeDef other) {
@@ -354,6 +362,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef
implements Serializable {
setOptions(other.getOptions());
setDescription((other.getDescription()));
setSearchWeight(other.getSearchWeight());
+ setIndexType(other.getIndexType());
}
}
@@ -365,6 +374,14 @@ public class AtlasStructDef extends AtlasBaseTypeDef
implements Serializable {
this.searchWeight = searchWeight;
}
+ public void setIndexType(IndexType indexType) {
+ this.indexType = indexType;
+ }
+
+ public IndexType getIndexType() {
+ return indexType;
+ }
+
public String getName() {
return name;
}
@@ -510,6 +527,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef
implements Serializable {
sb.append(", defaultValue=").append(defaultValue);
sb.append(", options='").append(options).append('\'');
sb.append(", searchWeight='").append(searchWeight).append('\'');
+ sb.append(", indexType='").append(indexType).append('\'');
sb.append(", constraints=[");
if (CollectionUtils.isNotEmpty(constraints)) {
int i = 0;
@@ -545,12 +563,13 @@ public class AtlasStructDef extends AtlasBaseTypeDef
implements Serializable {
Objects.equals(description, that.description) &&
Objects.equals(constraints, that.constraints) &&
Objects.equals(options, that.options) &&
- Objects.equals(searchWeight, that.searchWeight);
+ Objects.equals(searchWeight, that.searchWeight) &&
+ Objects.equals(indexType, that.indexType);
}
@Override
public int hashCode() {
- return Objects.hash(name, typeName, isOptional, cardinality,
valuesMinCount, valuesMaxCount, isUnique, isIndexable, includeInNotification,
defaultValue, constraints, options, description, searchWeight);
+ return Objects.hash(name, typeName, isOptional, cardinality,
valuesMinCount, valuesMaxCount, isUnique, isIndexable, includeInNotification,
defaultValue, constraints, options, description, searchWeight, indexType);
}
@Override
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
index e7ec3d8..e8bf7f9 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
@@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
import java.util.*;
import static org.apache.atlas.model.TypeCategory.OBJECT_ID_TYPE;
+import static
org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_STRING;
import static
org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.*;
/**
@@ -694,6 +695,7 @@ public class AtlasStructType extends AtlasType {
}
public static class AtlasAttribute {
+ public static final Object VERTEX_PROPERTY_PREFIX_STRING_INDEX_TYPE =
"__s_";
private final AtlasStructType definedInType;
private final AtlasType attributeType;
private final AtlasAttributeDef attributeDef;
@@ -718,14 +720,15 @@ public class AtlasStructType extends AtlasType {
this.attributeDef = attrDef;
this.attributeType =
attributeType.getTypeForAttribute();
this.qualifiedName =
getQualifiedAttributeName(definedInType.getStructDef(), attributeDef.getName());
- this.vertexPropertyName =
encodePropertyKey(this.qualifiedName);
+ this.vertexPropertyName =
generateVertexPropertyName(definedInType.getStructDef(), attributeDef,
qualifiedName);
this.vertexUniquePropertyName = attrDef.getIsUnique() ?
encodePropertyKey(getQualifiedAttributeName(definedInType.getStructDef(),
UNIQUE_ATTRIBUTE_SHADE_PROPERTY_PREFIX + attributeDef.getName())) : null;
this.relationshipName = relationshipName;
this.relationshipEdgeLabel =
getRelationshipEdgeLabel(relationshipLabel);
-
boolean isOwnedRef = false;
String inverseRefAttribute = null;
+ LOG.debug("Attribute {} will use the vertext property name {}.",
qualifiedName, vertexPropertyName);
+
if (CollectionUtils.isNotEmpty(attributeDef.getConstraints())) {
for (AtlasConstraintDef constraint :
attributeDef.getConstraints()) {
if
(constraint.isConstraintType(CONSTRAINT_TYPE_OWNED_REF)) {
@@ -829,6 +832,8 @@ public class AtlasStructType extends AtlasType {
public int getSearchWeight() { return attributeDef.getSearchWeight(); }
+ public AtlasAttributeDef.IndexType getIndexType() { return
attributeDef.getIndexType();}
+
public boolean getIsDynAttribute() { return isDynAttribute; }
public void setIsDynAttribute(boolean isDynAttribute){
this.isDynAttribute = isDynAttribute; }
@@ -910,9 +915,19 @@ public class AtlasStructType extends AtlasType {
return (relationshipLabel == null) ? getEdgeLabel(qualifiedName) :
relationshipLabel;
}
- private static String getQualifiedAttributeName(AtlasStructDef
structDef, String attrName) {
- final String typeName = structDef.getName();
- return attrName.contains(".") ? attrName : String.format("%s.%s",
typeName, attrName);
+ public static String getQualifiedAttributeName(AtlasStructDef
structDef, String attrName) {
+ return attrName.contains(".") ? attrName : String.format("%s.%s",
structDef.getName(), attrName);
+ }
+
+ public static String generateVertexPropertyName(AtlasStructDef
structDef, AtlasAttributeDef attrDef, String qualifiedName) {
+ String vertexPropertyName = qualifiedName;
+
+ if(!attrDef.getName().contains(".") &&
+
AtlasAttributeDef.IndexType.STRING.equals(attrDef.getIndexType()) &&
+ ATLAS_TYPE_STRING.equalsIgnoreCase(attrDef.getTypeName())) {
+ vertexPropertyName = String.format("%s.%s%s",
structDef.getName(), VERTEX_PROPERTY_PREFIX_STRING_INDEX_TYPE,
attrDef.getName());
+ }
+ return encodePropertyKey(vertexPropertyName);
}
// Keys copied from
org.janusgraph.graphdb.types.system.SystemTypeManager.RESERVED_CHARS
diff --git
a/intg/src/main/java/org/apache/atlas/v1/model/typedef/AttributeDefinition.java
b/intg/src/main/java/org/apache/atlas/v1/model/typedef/AttributeDefinition.java
index d9a3a81..cc801cb 100644
---
a/intg/src/main/java/org/apache/atlas/v1/model/typedef/AttributeDefinition.java
+++
b/intg/src/main/java/org/apache/atlas/v1/model/typedef/AttributeDefinition.java
@@ -21,8 +21,11 @@ package org.apache.atlas.v1.model.typedef;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
@@ -40,45 +43,46 @@ import static
org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.DE
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class AttributeDefinition implements Serializable {
- private static final long serialVersionUID = 1L;
- private String name;
- private String dataTypeName;
- private Multiplicity multiplicity;
- private boolean isComposite; // A composite is the one whose
lifecycle is dependent on the enclosing type and is not just a reference
- private boolean isUnique;
- private boolean isIndexable;
- private String reverseAttributeName; // If this is a reference
attribute, then the name of the attribute on the Class that this refers to.
- private String defaultValue;
- private String description;
- private Map<String, String> options;
- private int searchWeight = DEFAULT_SEARCHWEIGHT;
+ private static final long serialVersionUID = 1L;
+ private String name;
+ private String dataTypeName;
+ private Multiplicity multiplicity;
+ private boolean isComposite; // A
composite is the one whose lifecycle is dependent on the enclosing type and is
not just a reference
+ private boolean isUnique;
+ private boolean isIndexable;
+ private String reverseAttributeName;
// If this is a reference attribute, then the name of the attribute on the
Class that this refers to.
+ private String defaultValue;
+ private String description;
+ private Map<String, String> options;
+ private int searchWeight =
DEFAULT_SEARCHWEIGHT;
+ private AtlasStructDef.AtlasAttributeDef.IndexType indexType = null;
public AttributeDefinition() {
}
public AttributeDefinition(String name, String dataTypeName, Multiplicity
multiplicity) {
- this(name, dataTypeName, multiplicity, false, false, true, null, null,
DEFAULT_SEARCHWEIGHT);
+ this(name, dataTypeName, multiplicity, false, false, true, null, null,
DEFAULT_SEARCHWEIGHT, null);
}
public AttributeDefinition(String name, String dataTypeName, Multiplicity
multiplicity, boolean isComposite,
String reverseAttributeName) {
- this(name, dataTypeName, multiplicity, isComposite,
reverseAttributeName, DEFAULT_SEARCHWEIGHT);
+ this(name, dataTypeName, multiplicity, isComposite,
reverseAttributeName, DEFAULT_SEARCHWEIGHT, null);
}
public AttributeDefinition(String name, String dataTypeName, Multiplicity
multiplicity, boolean isComposite,
- String reverseAttributeName, int searchWeight) {
- this(name, dataTypeName, multiplicity, isComposite, false, false,
reverseAttributeName, null, searchWeight);
+ String reverseAttributeName, int searchWeight,
AtlasStructDef.AtlasAttributeDef.IndexType indexType) {
+ this(name, dataTypeName, multiplicity, isComposite, false, false,
reverseAttributeName, null, searchWeight, indexType);
}
public AttributeDefinition(String name, String dataTypeName, Multiplicity
multiplicity, boolean isComposite,
boolean isUnique, boolean isIndexable, String
reverseAttributeName,
Map<String, String> options) {
- this(name, dataTypeName, multiplicity, isComposite, isUnique,
isIndexable,reverseAttributeName, options, DEFAULT_SEARCHWEIGHT);
+ this(name, dataTypeName, multiplicity, isComposite, isUnique,
isIndexable,reverseAttributeName, options, DEFAULT_SEARCHWEIGHT, null);
}
public AttributeDefinition(String name, String dataTypeName, Multiplicity
multiplicity, boolean isComposite,
boolean isUnique, boolean isIndexable, String
reverseAttributeName,
- Map<String, String> options, int searchWeight) {
+ Map<String, String> options, int searchWeight,
AtlasStructDef.AtlasAttributeDef.IndexType indexType) {
this.name = name;
this.dataTypeName = dataTypeName;
this.multiplicity = multiplicity;
@@ -88,6 +92,7 @@ public class AttributeDefinition implements Serializable {
this.reverseAttributeName = reverseAttributeName;
this.options = options;
this.searchWeight = searchWeight;
+ this.indexType = indexType;
}
@@ -213,4 +218,12 @@ public class AttributeDefinition implements Serializable {
public int getSearchWeight() {
return searchWeight;
}
+
+ public void setIndexType(AtlasStructDef.AtlasAttributeDef.IndexType
indexType) {
+ this.indexType = indexType;
+ }
+
+ public AtlasStructDef.AtlasAttributeDef.IndexType getIndexType() {
+ return this.indexType;
+ }
}
diff --git
a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
index a7ccaeb..f7847ed 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
@@ -512,7 +512,10 @@ public abstract class SearchProcessor {
break;
}
- ret = predicate.generatePredicate(attribute.getQualifiedName(),
attrValue, attrClass);
+ String vertexPropertyName = attribute.getVertexPropertyName();
+ ret = predicate.generatePredicate(
+ StringUtils.isEmpty(vertexPropertyName) ?
attribute.getQualifiedName() : vertexPropertyName,
+ attrValue, attrClass);
}
return ret;
diff --git
a/repository/src/main/java/org/apache/atlas/query/GremlinClauseList.java
b/repository/src/main/java/org/apache/atlas/query/GremlinClauseList.java
index 7117977..9f30e4d 100644
--- a/repository/src/main/java/org/apache/atlas/query/GremlinClauseList.java
+++ b/repository/src/main/java/org/apache/atlas/query/GremlinClauseList.java
@@ -37,14 +37,6 @@ class GremlinClauseList {
list.add(idx, g);
}
- public void add(GremlinQueryComposer.GremlinClauseValue g, AtlasEntityType
t) {
- add(g);
- }
-
- public void add(int idx, GremlinQueryComposer.GremlinClauseValue g,
AtlasEntityType t) {
- add(idx, g);
- }
-
public void add(GremlinClause clause, String... args) {
list.add(new GremlinQueryComposer.GremlinClauseValue(clause,
clause.get(args)));
}
diff --git
a/repository/src/main/java/org/apache/atlas/query/GremlinQueryComposer.java
b/repository/src/main/java/org/apache/atlas/query/GremlinQueryComposer.java
index 17c837b..e64a894 100644
--- a/repository/src/main/java/org/apache/atlas/query/GremlinQueryComposer.java
+++ b/repository/src/main/java/org/apache/atlas/query/GremlinQueryComposer.java
@@ -177,6 +177,7 @@ public class GremlinQueryComposer {
introduceType(lhsI);
org = lhsI;
lhsI = createInfo(lhs);
+ lhsI.setTypeName(org.getTypeName());
}
if (!context.validator.isValidQualifiedName(lhsI.getQualifiedName(),
lhsI.getRaw())) {
@@ -192,11 +193,11 @@ public class GremlinQueryComposer {
rhs = addQuotesIfNecessary(lhsI, rhs);
SearchParameters.Operator op =
SearchParameters.Operator.fromString(operator);
if (op == SearchParameters.Operator.LIKE) {
- add(GremlinClause.TEXT_CONTAINS, lhsI.getQualifiedName(),
IdentifierHelper.getFixedRegEx(rhs));
+ add(GremlinClause.TEXT_CONTAINS, getPropertyForClause(lhsI),
IdentifierHelper.getFixedRegEx(rhs));
} else if (op == SearchParameters.Operator.IN) {
- add(GremlinClause.HAS_OPERATOR, lhsI.getQualifiedName(), "within",
rhs);
+ add(GremlinClause.HAS_OPERATOR, getPropertyForClause(lhsI),
"within", rhs);
} else {
- add(GremlinClause.HAS_OPERATOR, lhsI.getQualifiedName(),
op.getSymbols()[1], rhs);
+ add(GremlinClause.HAS_OPERATOR, getPropertyForClause(lhsI),
op.getSymbols()[1], rhs);
}
// record that the attribute has been processed so that the select
clause doesn't add a attr presence check
attributesProcessed.add(lhsI.getQualifiedName());
@@ -320,12 +321,12 @@ public class GremlinQueryComposer {
IdentifierHelper.Info ia = createInfo(name);
if (queryMetadata.hasSelect() && queryMetadata.hasGroupBy()) {
- addSelectTransformation(this.context.selectClauseComposer,
getQualifiedName(ia), isDesc);
+ addSelectTransformation(this.context.selectClauseComposer,
getPropertyForClause(ia), isDesc);
} else if (queryMetadata.hasGroupBy()) {
- addOrderByClause(getQualifiedName(ia), isDesc);
+ addOrderByClause(ia, isDesc);
moveToLast(GremlinClause.GROUP_BY);
} else {
- addOrderByClause(getQualifiedName(ia), isDesc);
+ addOrderByClause(ia, isDesc);
}
}
@@ -347,9 +348,17 @@ public class GremlinQueryComposer {
queryClauses.contains(GremlinClause.HAS_TYPE_WITHIN) !=
-1;
}
- private String getQualifiedName(IdentifierHelper.Info ia) {
- return context.validator.isValidQualifiedName(ia.getQualifiedName(),
ia.getRaw()) ?
- ia.getQualifiedName() : ia.getRaw();
+ private String getPropertyForClause(IdentifierHelper.Info ia) {
+ String vertexPropertyName =
lookup.getVertexPropertyName(ia.getTypeName(), ia.getAttributeName());
+ if (StringUtils.isNotEmpty(vertexPropertyName)) {
+ return vertexPropertyName;
+ }
+
+ if (StringUtils.isNotEmpty(ia.getQualifiedName())) {
+ return ia.getQualifiedName();
+ }
+
+ return ia.getRaw();
}
private void addSelectAttrExistsCheck(final SelectClauseComposer
selectClauseComposer) {
@@ -362,7 +371,7 @@ public class GremlinQueryComposer {
IdentifierHelper.Info idMetadata =
createInfo(qualifiedAttribute);
// Only primitive attributes need to be checked
if (idMetadata.isPrimitive() &&
!selectClauseComposer.isAggregatorIdx(i) &&
!attributesProcessed.contains(qualifiedAttribute)) {
- add(GremlinClause.HAS_PROPERTY, qualifiedAttribute);
+ add(GremlinClause.HAS_PROPERTY,
getPropertyForClause(idMetadata));
}
}
// All these checks should be done before the grouping happens (if
any)
@@ -388,10 +397,10 @@ public class GremlinQueryComposer {
}
if (!scc.getItem(i).equals(scc.getLabel(i))) {
- context.addAlias(scc.getLabel(i), getQualifiedName(ia));
+ context.addAlias(scc.getLabel(i), ia.getQualifiedName());
}
- if (scc.updateAsApplicable(i, getQualifiedName(ia))) {
+ if (scc.updateAsApplicable(i, getPropertyForClause(ia),
ia.getQualifiedName())) {
continue;
}
@@ -404,10 +413,10 @@ public class GremlinQueryComposer {
scc.incrementTypesIntroduced();
scc.isSelectNoop = !ia.hasParts();
if (ia.hasParts()) {
- scc.assign(i, getQualifiedName(createInfo(ia.get())),
GremlinClause.INLINE_GET_PROPERTY);
+ scc.assign(i, getPropertyForClause(createInfo(ia.get())),
GremlinClause.INLINE_GET_PROPERTY);
}
} else {
- scc.assign(i, getQualifiedName(ia),
GremlinClause.INLINE_GET_PROPERTY);
+ scc.assign(i, getPropertyForClause(ia),
GremlinClause.INLINE_GET_PROPERTY);
scc.incrementPrimitiveType();
}
}
@@ -456,16 +465,16 @@ public class GremlinQueryComposer {
private void addSelectTransformation(final SelectClauseComposer
selectClauseComposer,
final String orderByQualifiedAttrName,
final boolean isDesc) {
- GremlinClause fn;
+ GremlinClause gremlinClause;
if (selectClauseComposer.isSelectNoop) {
- fn = GremlinClause.SELECT_NOOP_FN;
+ gremlinClause = GremlinClause.SELECT_NOOP_FN;
} else if (queryMetadata.hasGroupBy()) {
- fn = selectClauseComposer.onlyAggregators() ?
GremlinClause.SELECT_ONLY_AGG_GRP_FN : GremlinClause.SELECT_MULTI_ATTR_GRP_FN;
+ gremlinClause = selectClauseComposer.onlyAggregators() ?
GremlinClause.SELECT_ONLY_AGG_GRP_FN : GremlinClause.SELECT_MULTI_ATTR_GRP_FN;
} else {
- fn = selectClauseComposer.onlyAggregators() ?
GremlinClause.SELECT_ONLY_AGG_FN : GremlinClause.SELECT_FN;
+ gremlinClause = selectClauseComposer.onlyAggregators() ?
GremlinClause.SELECT_ONLY_AGG_FN : GremlinClause.SELECT_FN;
}
if (StringUtils.isEmpty(orderByQualifiedAttrName)) {
- add(0, fn,
+ add(0, gremlinClause,
selectClauseComposer.getLabelHeader(),
selectClauseComposer.hasAssignmentExpr() ?
selectClauseComposer.getAssignmentExprString() : EMPTY_STRING,
selectClauseComposer.getItemsString(),
@@ -477,7 +486,7 @@ public class GremlinQueryComposer {
sortClause = isDesc ? GremlinClause.INLINE_TUPLE_SORT_DESC :
GremlinClause.INLINE_TUPLE_SORT_ASC;
}
String idxStr = String.valueOf(itemIdx);
- add(0, fn,
+ add(0, gremlinClause,
selectClauseComposer.getLabelHeader(),
selectClauseComposer.hasAssignmentExpr() ?
selectClauseComposer.getAssignmentExprString() : EMPTY_STRING,
selectClauseComposer.getItemsString(),
@@ -575,12 +584,11 @@ public class GremlinQueryComposer {
}
}
- private void addOrderByClause(String name, boolean descr) {
+ private void addOrderByClause(IdentifierHelper.Info ia, boolean descr) {
if (LOG.isDebugEnabled()) {
- LOG.debug("addOrderByClause(name={})", name, descr);
+ LOG.debug("addOrderByClause(name={})", ia.getRaw(), descr);
}
- IdentifierHelper.Info ia = createInfo(name);
add((!descr) ? GremlinClause.ORDER_BY : GremlinClause.ORDER_BY_DESC,
ia);
}
@@ -598,7 +606,7 @@ public class GremlinQueryComposer {
return;
}
- add(clause, (idInfo.getQualifiedName() == null ? idInfo.get() :
idInfo.getQualifiedName()));
+ add(clause, getPropertyForClause(idInfo));
}
private void add(GremlinClause clause, String... args) {
diff --git
a/repository/src/main/java/org/apache/atlas/query/IdentifierHelper.java
b/repository/src/main/java/org/apache/atlas/query/IdentifierHelper.java
index e74c0f5..0fdb57b 100644
--- a/repository/src/main/java/org/apache/atlas/query/IdentifierHelper.java
+++ b/repository/src/main/java/org/apache/atlas/query/IdentifierHelper.java
@@ -33,6 +33,9 @@ public class IdentifierHelper {
public static String get(String quotedIdentifier) {
String ret;
+ if (StringUtils.isEmpty(quotedIdentifier)) {
+ return null;
+ }
if (quotedIdentifier.charAt(0) == '`') {
ret = extract(BACKTICK_QUOTED_IDENTIFIER, quotedIdentifier);
@@ -74,20 +77,25 @@ public class IdentifierHelper {
public static boolean isQuoted(String val) {
boolean ret = false;
+ if (StringUtils.isEmpty(val)) {
+ return ret;
+ }
- if (val != null && val.length() > 1) {
- char first = val.charAt(0);
- char last = val.charAt(val.length() - 1);
+ char first = val.charAt(0);
+ char last = val.charAt(val.length() - 1);
- if (first == last && (first == '\'' || first == '"' || first ==
'`')) {
- ret = true;
- }
+ if (first == last && (first == '\'' || first == '"' || first == '`')) {
+ ret = true;
}
return ret;
}
public static String removeQuotes(String rhs) {
+ if (StringUtils.isEmpty(rhs)) {
+ return rhs;
+ }
+
return rhs.replace("\"", "")
.replace("'", "")
.replace("`", "");
@@ -294,5 +302,9 @@ public class IdentifierHelper {
public boolean isNumeric() {
return isNumeric;
}
+
+ public void setTypeName(String typeName) {
+ this.typeName = typeName;
+ }
}
}
diff --git a/repository/src/main/java/org/apache/atlas/query/Lookup.java
b/repository/src/main/java/org/apache/atlas/query/Lookup.java
index ec95f5d..3c192d8 100644
--- a/repository/src/main/java/org/apache/atlas/query/Lookup.java
+++ b/repository/src/main/java/org/apache/atlas/query/Lookup.java
@@ -43,4 +43,6 @@ public interface Lookup {
boolean isDate(GremlinQueryComposer.Context context, String attributeName);
boolean isNumeric(GremlinQueryComposer.Context context, String attrName);
+
+ String getVertexPropertyName(String typeName, String attrName);
}
diff --git
a/repository/src/main/java/org/apache/atlas/query/RegistryBasedLookup.java
b/repository/src/main/java/org/apache/atlas/query/RegistryBasedLookup.java
index e67eeaf..2878a74 100644
--- a/repository/src/main/java/org/apache/atlas/query/RegistryBasedLookup.java
+++ b/repository/src/main/java/org/apache/atlas/query/RegistryBasedLookup.java
@@ -254,6 +254,17 @@ class RegistryBasedLookup implements Lookup {
return ret;
}
+ @Override
+ public String getVertexPropertyName(String typeName, String attrName) {
+ AtlasEntityType entityType =
typeRegistry.getEntityTypeByName(typeName);
+ AtlasStructType.AtlasAttribute attribute = getAttribute(entityType,
attrName);
+ if (attribute == null) {
+ return null;
+ }
+
+ return attribute.getVertexPropertyName();
+ }
+
private AtlasStructType.AtlasAttribute getAttribute(AtlasEntityType
entityType, String attrName) {
AtlasStructType.AtlasAttribute ret = null;
diff --git
a/repository/src/main/java/org/apache/atlas/query/SelectClauseComposer.java
b/repository/src/main/java/org/apache/atlas/query/SelectClauseComposer.java
index 999fe5c..fc74148 100644
--- a/repository/src/main/java/org/apache/atlas/query/SelectClauseComposer.java
+++ b/repository/src/main/java/org/apache/atlas/query/SelectClauseComposer.java
@@ -61,20 +61,16 @@ class SelectClauseComposer {
this.items = Arrays.copyOf(items, items.length);
}
- public boolean updateAsApplicable(int currentIndex, String qualifiedName) {
+ public boolean updateAsApplicable(int currentIndex, String
propertyForClause, String qualifiedName) {
boolean ret = false;
if (currentIndex == getCountIdx()) {
- ret = assign(currentIndex, COUNT_STR,
- GremlinClause.INLINE_COUNT.get(),
GremlinClause.INLINE_ASSIGNMENT);
+ ret = assign(currentIndex, COUNT_STR,
GremlinClause.INLINE_COUNT.get(), GremlinClause.INLINE_ASSIGNMENT);
} else if (currentIndex == getMinIdx()) {
- ret = assign(currentIndex, MIN_STR, qualifiedName,
- GremlinClause.INLINE_ASSIGNMENT, GremlinClause.INLINE_MIN);
+ ret = assign(currentIndex, MIN_STR, propertyForClause,
GremlinClause.INLINE_ASSIGNMENT, GremlinClause.INLINE_MIN);
} else if (currentIndex == getMaxIdx()) {
- ret = assign(currentIndex, MAX_STR, qualifiedName,
- GremlinClause.INLINE_ASSIGNMENT, GremlinClause.INLINE_MAX);
+ ret = assign(currentIndex, MAX_STR, propertyForClause,
GremlinClause.INLINE_ASSIGNMENT, GremlinClause.INLINE_MAX);
} else if (currentIndex == getSumIdx()) {
- ret = assign(currentIndex, SUM_STR, qualifiedName,
- GremlinClause.INLINE_ASSIGNMENT, GremlinClause.INLINE_SUM);
+ ret = assign(currentIndex, SUM_STR, propertyForClause,
GremlinClause.INLINE_ASSIGNMENT, GremlinClause.INLINE_SUM);
} else {
attributes[currentIndex] = qualifiedName;
}
diff --git
a/repository/src/main/java/org/apache/atlas/repository/converters/TypeConverterUtil.java
b/repository/src/main/java/org/apache/atlas/repository/converters/TypeConverterUtil.java
index a248de6..340da58 100644
---
a/repository/src/main/java/org/apache/atlas/repository/converters/TypeConverterUtil.java
+++
b/repository/src/main/java/org/apache/atlas/repository/converters/TypeConverterUtil.java
@@ -307,7 +307,10 @@ public final class TypeConverterUtil {
}
public static AtlasAttributeDef toAtlasAttributeDef(final
AttributeDefinition attrDefinition) {
- AtlasAttributeDef ret = new
AtlasAttributeDef(attrDefinition.getName(), attrDefinition.getDataTypeName(),
attrDefinition.getSearchWeight());
+ AtlasAttributeDef ret = new AtlasAttributeDef(attrDefinition.getName(),
+
attrDefinition.getDataTypeName(),
+
attrDefinition.getSearchWeight(),
+
attrDefinition.getIndexType());
ret.setIsIndexable(attrDefinition.getIsIndexable());
ret.setIsUnique(attrDefinition.getIsUnique());
@@ -362,7 +365,16 @@ public final class TypeConverterUtil {
AttributeDefinition oldAttrDef =
AtlasStructDefStoreV2.toAttributeDefinition(attribute);
- ret.add(new AttributeDefinition(oldAttrDef.getName(),
oldAttrDef.getDataTypeName(), new Multiplicity(oldAttrDef.getMultiplicity()),
oldAttrDef.getIsComposite(), oldAttrDef.getIsUnique(),
oldAttrDef.getIsIndexable(), oldAttrDef.getReverseAttributeName(),
oldAttrDef.getOptions(), oldAttrDef.getSearchWeight()));
+ ret.add(new AttributeDefinition(oldAttrDef.getName(),
+ oldAttrDef.getDataTypeName(),
+ new
Multiplicity(oldAttrDef.getMultiplicity()),
+ oldAttrDef.getIsComposite(),
+ oldAttrDef.getIsUnique(),
+ oldAttrDef.getIsIndexable(),
+
oldAttrDef.getReverseAttributeName(),
+ oldAttrDef.getOptions(),
+ oldAttrDef.getSearchWeight(),
+ oldAttrDef.getIndexType()));
}
}
diff --git
a/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
b/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
index 255050d..a1776c8 100755
---
a/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
+++
b/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
@@ -316,9 +316,9 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
createCommonVertexIndex(management, TIMESTAMP_PROPERTY_KEY,
UniqueKind.NONE, Long.class, SINGLE, false, false);
createCommonVertexIndex(management,
MODIFICATION_TIMESTAMP_PROPERTY_KEY, UniqueKind.NONE, Long.class, SINGLE,
false, false);
createCommonVertexIndex(management, STATE_PROPERTY_KEY,
UniqueKind.NONE, String.class, SINGLE, false, false);
- createCommonVertexIndex(management, CREATED_BY_KEY,
UniqueKind.NONE, String.class, SINGLE, false, false);
+ createCommonVertexIndex(management, CREATED_BY_KEY,
UniqueKind.NONE, String.class, SINGLE, false, false, true);
createCommonVertexIndex(management, CLASSIFICATION_TEXT_KEY,
UniqueKind.NONE, String.class, SINGLE, false, false);
- createCommonVertexIndex(management, MODIFIED_BY_KEY,
UniqueKind.NONE, String.class, SINGLE, false, false);
+ createCommonVertexIndex(management, MODIFIED_BY_KEY,
UniqueKind.NONE, String.class, SINGLE, false, false, true);
createCommonVertexIndex(management, CLASSIFICATION_NAMES_KEY,
UniqueKind.NONE, String.class, SINGLE, true, false);
createCommonVertexIndex(management,
PROPAGATED_CLASSIFICATION_NAMES_KEY, UniqueKind.NONE, String.class, SINGLE,
true, false);
createCommonVertexIndex(management, TRAIT_NAMES_PROPERTY_KEY,
UniqueKind.NONE, String.class, SET, true, true);
@@ -395,9 +395,9 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
attribute.setIndexFieldName(baseInstance.getIndexFieldName());
} else if
(isIndexApplicable(getPrimitiveClass(attribute.getTypeName()),
toAtlasCardinality(attribute.getAttributeDef().getCardinality()))) {
AtlasPropertyKey propertyKey =
managementSystem.getPropertyKey(attribute.getVertexPropertyName());
-
+ boolean isStringField =
AtlasAttributeDef.IndexType.STRING.equals(attribute.getIndexType());
if (propertyKey != null) {
- String indexFieldName =
managementSystem.getIndexFieldName(Constants.VERTEX_INDEX, propertyKey);
+ String indexFieldName =
managementSystem.getIndexFieldName(Constants.VERTEX_INDEX, propertyKey,
isStringField);
attribute.setIndexFieldName(indexFieldName);
@@ -425,13 +425,30 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
AtlasCardinality cardinality,
boolean createCompositeIndex,
boolean
createCompositeIndexWithTypeAndSuperTypes) {
+ createCommonVertexIndex(management, propertyName, uniqueKind,
propertyClass, cardinality, createCompositeIndex,
createCompositeIndexWithTypeAndSuperTypes, false);
+ }
+
+ private void createCommonVertexIndex(AtlasGraphManagement management,
+ String propertyName,
+ UniqueKind uniqueKind,
+ Class propertyClass,
+ AtlasCardinality cardinality,
+ boolean createCompositeIndex,
+ boolean
createCompositeIndexWithTypeAndSuperTypes,
+ boolean isStringField) {
+ if(isStringField && String.class.equals(propertyClass)) {
+
+ propertyName =
AtlasAttribute.VERTEX_PROPERTY_PREFIX_STRING_INDEX_TYPE +propertyName;
+ LOG.debug("Creating the common attribute '{}' as string field.",
propertyName);
+ }
+
final String indexFieldName = createVertexIndex(management,
- propertyName,
- uniqueKind,
- propertyClass,
- cardinality,
- createCompositeIndex,
-
createCompositeIndexWithTypeAndSuperTypes);
+ propertyName,
+ uniqueKind,
+ propertyClass,
+ cardinality,
+ createCompositeIndex,
+
createCompositeIndexWithTypeAndSuperTypes, isStringField);
if(indexFieldName != null) {
typeRegistry.addIndexFieldName(propertyName, indexFieldName);
}
@@ -447,7 +464,7 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
List<AtlasAttributeDef> attributeDefs =
structDef.getAttributeDefs();
if (CollectionUtils.isNotEmpty(attributeDefs)) {
for (AtlasAttributeDef attributeDef : attributeDefs) {
- createIndexForAttribute(management, typeDef.getName(),
attributeDef);
+ createIndexForAttribute(management, structDef,
attributeDef);
}
}
} else if (!AtlasTypeUtil.isBuiltInType(typeDef.getName())){
@@ -476,8 +493,9 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
LOG.info("Completed deleting indexes for type {}", typeDef.getName());
}
- private void createIndexForAttribute(AtlasGraphManagement management,
String typeName, AtlasAttributeDef attributeDef) {
- final String propertyName = getEncodedPropertyName(typeName,
attributeDef);
+ private void createIndexForAttribute(AtlasGraphManagement management,
AtlasStructDef structDef, AtlasAttributeDef attributeDef) {
+ String qualifiedName =
AtlasAttribute.getQualifiedAttributeName(structDef, attributeDef.getName());
+ final String propertyName =
AtlasAttribute.generateVertexPropertyName(structDef, attributeDef,
qualifiedName);
AtlasCardinality cardinality =
toAtlasCardinality(attributeDef.getCardinality());
boolean isUnique = attributeDef.getIsUnique();
boolean isIndexable = attributeDef.getIsIndexable();
@@ -485,10 +503,11 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
boolean isBuiltInType =
AtlasTypeUtil.isBuiltInType(attribTypeName);
boolean isArrayType = isArrayType(attribTypeName);
boolean isMapType = isMapType(attribTypeName);
- final String uniqPropName = isUnique ?
AtlasGraphUtilsV2.encodePropertyKey(typeName + "." +
UNIQUE_ATTRIBUTE_SHADE_PROPERTY_PREFIX + attributeDef.getName()) : null;
+ final String uniqPropName = isUnique ?
AtlasGraphUtilsV2.encodePropertyKey(structDef.getName() + "." +
UNIQUE_ATTRIBUTE_SHADE_PROPERTY_PREFIX + attributeDef.getName()) : null;
+ final AtlasAttributeDef.IndexType indexType =
attributeDef.getIndexType();
try {
- AtlasType atlasType = typeRegistry.getType(typeName);
+ AtlasType atlasType =
typeRegistry.getType(structDef.getName());
AtlasType attributeType = typeRegistry.getType(attribTypeName);
if (isClassificationType(attributeType)) {
@@ -524,25 +543,31 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
if (isRelationshipType(atlasType)) {
createEdgeIndex(management, propertyName,
getPrimitiveClass(attribTypeName), cardinality, false);
} else {
- createVertexIndex(management, propertyName,
UniqueKind.NONE, getPrimitiveClass(attribTypeName), cardinality, isIndexable,
false);
+ Class primitiveClassType =
getPrimitiveClass(attribTypeName);
+ boolean isStringField = false;
+ if(primitiveClassType == String.class) {
+ isStringField =
AtlasAttributeDef.IndexType.STRING.equals(indexType);
+
+ }
+ createVertexIndex(management, propertyName,
UniqueKind.NONE, getPrimitiveClass(attribTypeName), cardinality, isIndexable,
false, isStringField);
if (uniqPropName != null) {
- createVertexIndex(management, uniqPropName,
UniqueKind.PER_TYPE_UNIQUE, getPrimitiveClass(attribTypeName), cardinality,
isIndexable, true);
+ createVertexIndex(management, uniqPropName,
UniqueKind.PER_TYPE_UNIQUE, getPrimitiveClass(attribTypeName), cardinality,
isIndexable, true, isStringField);
}
}
} else if (isEnumType(attributeType)) {
if (isRelationshipType(atlasType)) {
createEdgeIndex(management, propertyName, String.class,
cardinality, false);
} else {
- createVertexIndex(management, propertyName,
UniqueKind.NONE, String.class, cardinality, isIndexable, false);
+ createVertexIndex(management, propertyName,
UniqueKind.NONE, String.class, cardinality, isIndexable, false, false);
if (uniqPropName != null) {
- createVertexIndex(management, uniqPropName,
UniqueKind.PER_TYPE_UNIQUE, String.class, cardinality, isIndexable, true);
+ createVertexIndex(management, uniqPropName,
UniqueKind.PER_TYPE_UNIQUE, String.class, cardinality, isIndexable, true,
false);
}
}
} else if (isStructType(attributeType)) {
- AtlasStructDef structDef =
typeRegistry.getStructDefByName(attribTypeName);
- updateIndexForTypeDef(management, structDef);
+ AtlasStructDef attribureStructDef =
typeRegistry.getStructDefByName(attribTypeName);
+ updateIndexForTypeDef(management, attribureStructDef);
}
} catch (AtlasBaseException e) {
LOG.error("No type exists for {}", attribTypeName, e);
@@ -565,12 +590,12 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
/**
* gets the encoded property name for the attribute passed in.
- * @param typeName the type system of the attribute
+ * @param baseTypeDef the type system of the attribute
* @param attributeDef the attribute definition
* @return the encoded property name for the attribute passed in.
*/
- public static String getEncodedPropertyName(String typeName,
AtlasAttributeDef attributeDef) {
- return AtlasGraphUtilsV2.encodePropertyKey(typeName + "." +
attributeDef.getName());
+ public static String getEncodedPropertyName(AtlasStructDef baseTypeDef,
AtlasAttributeDef attributeDef) {
+ return AtlasAttribute.getQualifiedAttributeName(baseTypeDef,
attributeDef.getName());
}
private void createLabelIfNeeded(final AtlasGraphManagement management,
final String propertyName, final String attribTypeName) {
@@ -673,7 +698,7 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
}
public String createVertexIndex(AtlasGraphManagement management, String
propertyName, UniqueKind uniqueKind, Class propertyClass,
- AtlasCardinality cardinality, boolean
createCompositeIndex, boolean createCompositeIndexWithTypeAndSuperTypes) {
+ AtlasCardinality cardinality, boolean
createCompositeIndex, boolean createCompositeIndexWithTypeAndSuperTypes,
boolean isStringField) {
String indexFieldName = null;
if (propertyName != null) {
@@ -687,13 +712,13 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
LOG.debug("Creating backing index for vertex property
{} of type {} ", propertyName, propertyClass.getName());
}
- indexFieldName = management.addMixedIndex(VERTEX_INDEX,
propertyKey);
+ indexFieldName = management.addMixedIndex(VERTEX_INDEX,
propertyKey, isStringField);
LOG.info("Created backing index for vertex property {} of
type {} ", propertyName, propertyClass.getName());
}
}
if(indexFieldName == null) {
- indexFieldName = management.getIndexFieldName(VERTEX_INDEX,
propertyKey);
+ indexFieldName = management.getIndexFieldName(VERTEX_INDEX,
propertyKey, isStringField);
}
if (propertyKey != null) {
@@ -775,7 +800,7 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
LOG.debug("Creating backing index for edge property {}
of type {} ", propertyName, propertyClass.getName());
}
- management.addMixedIndex(EDGE_INDEX, propertyKey);
+ management.addMixedIndex(EDGE_INDEX, propertyKey, false);
LOG.info("Created backing index for edge property {} of
type {} ", propertyName, propertyClass.getName());
}
@@ -803,7 +828,7 @@ public class GraphBackedSearchIndexer implements
SearchIndexer, ActiveStateChang
LOG.debug("Creating backing index for vertex property {}
of type {} ", propertyName, propertyClass.getName());
}
- management.addMixedIndex(FULLTEXT_INDEX, propertyKey);
+ management.addMixedIndex(FULLTEXT_INDEX, propertyKey, false);
LOG.info("Created backing index for vertex property {} of type
{} ", propertyName, propertyClass.getName());
}
diff --git
a/repository/src/main/java/org/apache/atlas/repository/patches/UniqueAttributePatch.java
b/repository/src/main/java/org/apache/atlas/repository/patches/UniqueAttributePatch.java
index bd5f525..bd5e32b 100644
---
a/repository/src/main/java/org/apache/atlas/repository/patches/UniqueAttributePatch.java
+++
b/repository/src/main/java/org/apache/atlas/repository/patches/UniqueAttributePatch.java
@@ -138,7 +138,14 @@ public class UniqueAttributePatch extends
AtlasPatchHandler {
Class propertyClass =
getIndexer().getPrimitiveClass(attribTypeName);
AtlasCardinality cardinality =
getIndexer().toAtlasCardinality(attributeDef.getCardinality());
- getIndexer().createVertexIndex(management,
uniquePropertyName, UniqueKind.PER_TYPE_UNIQUE, propertyClass, cardinality,
isIndexable, true);
+ getIndexer().createVertexIndex(management,
+ uniquePropertyName,
+ UniqueKind.PER_TYPE_UNIQUE,
+ propertyClass,
+ cardinality,
+ isIndexable,
+ true,
+
AtlasAttributeDef.IndexType.STRING.equals(attribute.getIndexType()));
}
getIndexer().commit(management);
diff --git
a/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
b/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
index 8d7dbfb..08b00e7 100644
---
a/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
+++
b/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
@@ -55,6 +55,7 @@ import org.apache.commons.collections.MapUtils;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.jute.Index;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
@@ -1041,6 +1042,18 @@ public class AtlasTypeDefStoreInitializer implements
ActiveStateChangeHandler {
}
atlasAttributeDef.setSearchWeight(searchWeight);
LOG.info("Updating Model attribute {}'s property{}
to {}.", atlasAttributeDef.getName(), entry.getKey(), entry.getValue());
+ } else if
(AtlasAttributeDef.INDEX_TYPE_ATTR_NAME.equalsIgnoreCase(entry.getKey())) {
+ String indexTypeString = (String) entry.getValue();
+ if(!StringUtils.isEmpty(indexTypeString)) {
+ try {
+ AtlasAttributeDef.IndexType indexType =
AtlasAttributeDef.IndexType.valueOf(indexTypeString);
+ atlasAttributeDef.setIndexType(indexType);
+ } catch (IllegalArgumentException e) {
+ String msg = String.format("Value %s
provided for the attribute %s is not valid.", indexTypeString,
AtlasAttributeDef.INDEX_TYPE_ATTR_NAME);
+ LOG.error(msg);
+ throw new RuntimeException(msg);
+ }
+ }
} else {
//sanity exception
//more attributes can be added as needed.
diff --git
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasStructDefStoreV2.java
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasStructDefStoreV2.java
index b93faf0..57c30f4 100644
---
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasStructDefStoreV2.java
+++
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasStructDefStoreV2.java
@@ -540,6 +540,7 @@ public class AtlasStructDefStoreV2 extends
AtlasAbstractDefStoreV2<AtlasStructDe
attribInfo.put("defaultValue", attributeDef.getDefaultValue());
attribInfo.put("description", attributeDef.getDescription());
attribInfo.put("searchWeight", attributeDef.getSearchWeight());
+ attribInfo.put("indexType", attributeDef.getIndexType());
if(attributeDef.getOptions() != null) {
attribInfo.put("options",
AtlasType.toJson(attributeDef.getOptions()));
@@ -634,6 +635,11 @@ public class AtlasStructDefStoreV2 extends
AtlasAbstractDefStoreV2<AtlasStructDe
} else {
ret.setSearchWeight(-1);
}
+
+ String indexType = (String) attribInfo.get("indexType");
+ if(!StringUtils.isEmpty(indexType)) {
+ ret.setIndexType(AtlasAttributeDef.IndexType.valueOf(indexType));
+ }
return ret;
}
@@ -652,7 +658,7 @@ public class AtlasStructDefStoreV2 extends
AtlasAbstractDefStoreV2<AtlasStructDe
ret.setDescription(attrDef.getDescription());
ret.setDefaultValue(attrDef.getDefaultValue());
ret.setSearchWeight(attrDef.getSearchWeight());
-
+ ret.setIndexType(attrDef.getIndexType());
return ret;
}
}
diff --git
a/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
b/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
index 5686670..b73d427 100644
---
a/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
+++
b/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
@@ -162,7 +162,7 @@ public class GremlinQueryComposerTest {
verify("from DB where name = \"Reporting\" select name, owner",
getExpected(exSel, exMain));
verify("from DB where (name = \"Reporting\") select name, owner",
getExpected(exSel, exMain));
verify("Table where Asset.name like \"Tab*\"",
- "g.V().has('__typeName', 'Table').has('Table.name',
org.janusgraph.core.attribute.Text.textRegex(\"Tab.*\")).dedup().limit(25).toList()");
+ "g.V().has('__typeName', 'Table').has('Asset.__s_name',
org.janusgraph.core.attribute.Text.textRegex(\"Tab.*\")).dedup().limit(25).toList()");
verify("from Table where (db.name = \"Reporting\")",
"g.V().has('__typeName',
'Table').out('__Table.db').has('DB.name',
eq(\"Reporting\")).dedup().in('__Table.db').dedup().limit(25).toList()");
}
@@ -184,8 +184,8 @@ public class GremlinQueryComposerTest {
@Test
public void subType() {
- String exMain = "g.V().has('__typeName',
within('Asset','Table')).has('Asset.name').has('Asset.owner').dedup().limit(25).toList()";
- String exSel = "def f(r){ t=[['name','owner']];
r.each({t.add([it.value('Asset.name'),it.value('Asset.owner')])}); t.unique();
}";
+ String exMain = "g.V().has('__typeName',
within('Asset','Table')).has('Asset.__s_name').has('Asset.__s_owner').dedup().limit(25).toList()";
+ String exSel = "def f(r){ t=[['name','owner']];
r.each({t.add([it.value('Asset.__s_name'),it.value('Asset.__s_owner')])});
t.unique(); }";
verify("Asset select name, owner", getExpected(exSel, exMain));
}
@@ -343,8 +343,8 @@ public class GremlinQueryComposerTest {
verify("Table has db", 1);
verify("Table groupby(db) select name", 1);
verify("Table groupby(name) select name, max(db)", 1);
- verify("Table select db, columns", 2);
- verify("Table select db, owner, columns", 3);
+ verify("Table select db, columns", 1);
+ verify("Table select db, owner, columns", 2);
}
private void verify(String dsl, String expectedGremlin, int
expectedNumberOfErrors) {
@@ -530,5 +530,16 @@ public class GremlinQueryComposerTest {
context.setNumericTypeFormatter("f");
return attrName.equals("partitionSize");
}
+
+ @Override
+ public String getVertexPropertyName(String typeName, String attrName) {
+ if (typeName.equals("Asset")) {
+ if (attrName.equals("name") || attrName.equals("owner")) {
+ return String.format("%s.__s_%s", typeName, attrName);
+ }
+ }
+
+ return null;
+ }
}
}
diff --git
a/webapp/src/test/resources/json/search-parameters/combination-filters.json
b/webapp/src/test/resources/json/search-parameters/combination-filters.json
index ea8fbda..dc52d33 100644
--- a/webapp/src/test/resources/json/search-parameters/combination-filters.json
+++ b/webapp/src/test/resources/json/search-parameters/combination-filters.json
@@ -139,7 +139,7 @@
"typeName": "hdfs_path",
"excludeDeletedEntities": true,
"classification" : "fooTag",
- "query": "test ; \\{ \\} \\[ \\]",
+ "query": "test",
"limit": 25,
"offset": 0,
"entityFilters": null,
@@ -169,7 +169,7 @@
"typeName": "hdfs_path",
"excludeDeletedEntities": true,
"classification" : "fooTag",
- "query": "test ; \\{ \\} \\[ \\]",
+ "query": "test",
"limit": 25,
"offset": 0,
"entityFilters": {