Commit d30fa2c2 by Sarath Subramanian Committed by Madhan Neethiraj

ATLAS-1761: improve attribute search to enable search based on display text

parent c4fc5b4f
...@@ -64,6 +64,7 @@ import javax.inject.Inject; ...@@ -64,6 +64,7 @@ import javax.inject.Inject;
import javax.script.ScriptEngine; import javax.script.ScriptEngine;
import javax.script.ScriptException; import javax.script.ScriptException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
...@@ -199,34 +200,53 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { ...@@ -199,34 +200,53 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
ret.setClassification(classification); ret.setClassification(classification);
} }
boolean isAttributeSearch = StringUtils.isNotEmpty(attrName) && StringUtils.isNotEmpty(attrValuePrefix); boolean isAttributeSearch = StringUtils.isNotEmpty(attrName) || StringUtils.isNotEmpty(attrValuePrefix);
boolean isGuidPrefixSearch = false;
if (isAttributeSearch) { if (isAttributeSearch) {
if (LOG.isDebugEnabled()) {
LOG.debug("Executing attribute search attrName: {} and attrValue: {}", attrName, attrValuePrefix);
}
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName); AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName);
ret.setQueryType(AtlasQueryType.ATTRIBUTE);
if (entityType != null) { if (entityType != null) {
AtlasAttribute attribute = entityType.getAttribute(attrName); AtlasAttribute attribute = null;
if (attribute == null) { if (StringUtils.isNotEmpty(attrName)) {
throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_ATTRIBUTE, attrName, typeName); 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);
}
} }
attrQualifiedName = entityType.getAttribute(attrName).getQualifiedName(); 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("\\.", " ")); String attrQuery = String.format("%s AND (%s *)", attrName, attrValuePrefix.replaceAll("\\.", " "));
if (StringUtils.isEmpty(query)) { query = StringUtils.isEmpty(query) ? attrQuery : String.format("(%s) AND (%s)", query, attrQuery);
query = attrQuery; }
} else {
query = String.format("(%s) AND (%s)", query, attrQuery);
} }
ret.setQueryType(AtlasQueryType.ATTRIBUTE); if (LOG.isDebugEnabled()) {
LOG.debug("Executing attribute search attrName: {} and attrValue: {}", attrName, attrValuePrefix);
}
} }
// if query was provided, perform indexQuery and filter for typeName & classification in memory; this approach // if query was provided, perform indexQuery and filter for typeName & classification in memory; this approach
...@@ -304,6 +324,12 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { ...@@ -304,6 +324,12 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
basicQuery += gremlinQueryProvider.getQuery(AtlasGremlinQuery.BASIC_SEARCH_TYPE_FILTER); 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("startIdx", params.offset());
bindings.put("endIdx", params.offset() + params.limit()); bindings.put("endIdx", params.offset() + params.limit());
......
...@@ -71,6 +71,8 @@ public class AtlasGremlin2QueryProvider extends AtlasGremlinQueryProvider { ...@@ -71,6 +71,8 @@ public class AtlasGremlin2QueryProvider extends AtlasGremlinQueryProvider {
return ".has('__traitNames', T.in, traitNames)"; return ".has('__traitNames', T.in, traitNames)";
case TO_RANGE_LIST: case TO_RANGE_LIST:
return " [startIdx..<endIdx].toList()"; return " [startIdx..<endIdx].toList()";
case GUID_PREFIX_FILTER:
return ".filter{it.'__guid'.matches(guid)}";
} }
// Should never reach this point // Should never reach this point
return null; return null;
......
...@@ -58,6 +58,7 @@ public abstract class AtlasGremlinQueryProvider { ...@@ -58,6 +58,7 @@ public abstract class AtlasGremlinQueryProvider {
// Discovery Queries // Discovery Queries
BASIC_SEARCH_TYPE_FILTER, BASIC_SEARCH_TYPE_FILTER,
BASIC_SEARCH_CLASSIFICATION_FILTER, BASIC_SEARCH_CLASSIFICATION_FILTER,
TO_RANGE_LIST TO_RANGE_LIST,
GUID_PREFIX_FILTER
} }
} }
...@@ -199,7 +199,7 @@ public class DiscoveryREST { ...@@ -199,7 +199,7 @@ public class DiscoveryREST {
attrValuePrefix + "," + typeName + "," + limit + "," + offset + ")"); attrValuePrefix + "," + typeName + "," + limit + "," + offset + ")");
} }
if (StringUtils.isEmpty(attrName) || StringUtils.isEmpty(attrValuePrefix)) { if (StringUtils.isEmpty(attrName) && StringUtils.isEmpty(attrValuePrefix)) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS,
String.format("attrName : {0}, attrValue: {1} for attribute search.", attrName, attrValuePrefix)); String.format("attrName : {0}, attrValue: {1} for attribute search.", attrName, attrValuePrefix));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment