ATLAS-1761: improve attribute search to enable search based on display text
Signed-off-by: Madhan Neethiraj <madhan@apache.org>
diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
index f3f6ee2..874487c 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
@@ -64,6 +64,7 @@
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -199,34 +200,53 @@
ret.setClassification(classification);
}
- boolean isAttributeSearch = StringUtils.isNotEmpty(attrName) && StringUtils.isNotEmpty(attrValuePrefix);
+ boolean isAttributeSearch = StringUtils.isNotEmpty(attrName) || StringUtils.isNotEmpty(attrValuePrefix);
+ boolean isGuidPrefixSearch = false;
if (isAttributeSearch) {
+ AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName);
+
+ ret.setQueryType(AtlasQueryType.ATTRIBUTE);
+
+ if (entityType != null) {
+ AtlasAttribute attribute = null;
+
+ if (StringUtils.isNotEmpty(attrName)) {
+ attribute = entityType.getAttribute(attrName);
+
+ if (attribute == null) {
+ throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_ATTRIBUTE, attrName, typeName);
+ }
+
+ } else {
+ // if attrName is null|empty iterate defaultAttrNames to get attribute value
+ final List<String> defaultAttrNames = new ArrayList<>(Arrays.asList("qualifiedName", "name"));
+ Iterator<String> iter = defaultAttrNames.iterator();
+
+ while (iter.hasNext() && attribute == null) {
+ attrName = iter.next();
+ attribute = entityType.getAttribute(attrName);
+ }
+ }
+
+ if (attribute == null) {
+ // for guid prefix search use gremlin and nullify query to avoid using fulltext
+ // (guids cannot be searched in fulltext)
+ isGuidPrefixSearch = true;
+ query = null;
+
+ } else {
+ attrQualifiedName = attribute.getQualifiedName();
+
+ String attrQuery = String.format("%s AND (%s *)", attrName, attrValuePrefix.replaceAll("\\.", " "));
+
+ query = StringUtils.isEmpty(query) ? attrQuery : String.format("(%s) AND (%s)", query, attrQuery);
+ }
+ }
+
if (LOG.isDebugEnabled()) {
LOG.debug("Executing attribute search attrName: {} and attrValue: {}", attrName, attrValuePrefix);
}
-
- AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName);
-
- if (entityType != null) {
- AtlasAttribute attribute = entityType.getAttribute(attrName);
-
- if (attribute == null) {
- throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_ATTRIBUTE, attrName, typeName);
- }
-
- attrQualifiedName = entityType.getAttribute(attrName).getQualifiedName();
- }
-
- String attrQuery = String.format("%s AND (%s *)", attrName, attrValuePrefix.replaceAll("\\.", " "));
-
- if (StringUtils.isEmpty(query)) {
- query = attrQuery;
- } else {
- query = String.format("(%s) AND (%s)", query, attrQuery);
- }
-
- ret.setQueryType(AtlasQueryType.ATTRIBUTE);
}
// if query was provided, perform indexQuery and filter for typeName & classification in memory; this approach
@@ -304,6 +324,12 @@
basicQuery += gremlinQueryProvider.getQuery(AtlasGremlinQuery.BASIC_SEARCH_TYPE_FILTER);
}
+ if (isGuidPrefixSearch) {
+ bindings.put("guid", attrValuePrefix + ".*");
+
+ basicQuery += gremlinQueryProvider.getQuery(AtlasGremlinQuery.GUID_PREFIX_FILTER);
+ }
+
bindings.put("startIdx", params.offset());
bindings.put("endIdx", params.offset() + params.limit());
diff --git a/repository/src/main/java/org/apache/atlas/util/AtlasGremlin2QueryProvider.java b/repository/src/main/java/org/apache/atlas/util/AtlasGremlin2QueryProvider.java
index d3413c2..139e7c3 100644
--- a/repository/src/main/java/org/apache/atlas/util/AtlasGremlin2QueryProvider.java
+++ b/repository/src/main/java/org/apache/atlas/util/AtlasGremlin2QueryProvider.java
@@ -71,6 +71,8 @@
return ".has('__traitNames', T.in, traitNames)";
case TO_RANGE_LIST:
return " [startIdx..<endIdx].toList()";
+ case GUID_PREFIX_FILTER:
+ return ".filter{it.'__guid'.matches(guid)}";
}
// Should never reach this point
return null;
diff --git a/repository/src/main/java/org/apache/atlas/util/AtlasGremlinQueryProvider.java b/repository/src/main/java/org/apache/atlas/util/AtlasGremlinQueryProvider.java
index 633fad0..8fb1793 100644
--- a/repository/src/main/java/org/apache/atlas/util/AtlasGremlinQueryProvider.java
+++ b/repository/src/main/java/org/apache/atlas/util/AtlasGremlinQueryProvider.java
@@ -58,6 +58,7 @@
// Discovery Queries
BASIC_SEARCH_TYPE_FILTER,
BASIC_SEARCH_CLASSIFICATION_FILTER,
- TO_RANGE_LIST
+ TO_RANGE_LIST,
+ GUID_PREFIX_FILTER
}
}
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java
index 81dbe25..edaf3ef 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java
@@ -199,7 +199,7 @@
attrValuePrefix + "," + typeName + "," + limit + "," + offset + ")");
}
- if (StringUtils.isEmpty(attrName) || StringUtils.isEmpty(attrValuePrefix)) {
+ if (StringUtils.isEmpty(attrName) && StringUtils.isEmpty(attrValuePrefix)) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS,
String.format("attrName : {0}, attrValue: {1} for attribute search.", attrName, attrValuePrefix));
}