Commit ea653e03 by Sarath Subramanian

ATLAS-3591: Improve user-defined attributes search

parent eed7817e
......@@ -73,6 +73,8 @@ public abstract class SearchProcessor {
public static final String BRACE_OPEN_STR = "(";
public static final String BRACE_CLOSE_STR = ")";
public static final String ALL_TYPE_QUERY = "[* TO *]";
public static final char CUSTOM_ATTR_SEPARATOR = '=';
public static final String CUSTOM_ATTR_SEARCH_FORMAT = "\"\\\"%s\\\":\\\"%s\\\"\"";
private static final Map<SearchParameters.Operator, String> OPERATOR_MAP = new HashMap<>();
private static final Map<SearchParameters.Operator, VertexAttributePredicateGenerator> OPERATOR_PREDICATE_MAP = new HashMap<>();
......@@ -493,7 +495,13 @@ public abstract class SearchProcessor {
String qualifiedName = type.getQualifiedAttributeName(attrName);
String escapeIndexQueryValue = AtlasAttribute.escapeIndexQueryValue(attrVal);
ret = String.format(OPERATOR_MAP.get(op), qualifiedName, escapeIndexQueryValue);
// map '__customAttributes' 'CONTAINS' operator to 'EQ' operator (solr limitation for json serialized string search)
// map '__customAttributes' value from 'key1=value1' to '\"key1\":\"value1\"' (escape special characters and surround with quotes)
if (attrName.equals(CUSTOM_ATTRIBUTES_PROPERTY_KEY) && op == SearchParameters.Operator.CONTAINS) {
ret = String.format(OPERATOR_MAP.get(SearchParameters.Operator.EQ), qualifiedName, getCustomAttributeIndexQueryValue(escapeIndexQueryValue));
} else {
ret = String.format(OPERATOR_MAP.get(op), qualifiedName, escapeIndexQueryValue);
}
}
} catch (AtlasBaseException ex) {
LOG.warn(ex.getMessage());
......@@ -502,6 +510,24 @@ public abstract class SearchProcessor {
return ret;
}
private String getCustomAttributeIndexQueryValue(String attrValue) {
String ret = null;
if (StringUtils.isNotEmpty(attrValue)) {
int separatorIdx = attrValue.indexOf(CUSTOM_ATTR_SEPARATOR);
String key = separatorIdx != -1 ? attrValue.substring(0, separatorIdx) : null;
String value = key != null ? attrValue.substring(separatorIdx + 1) : null;
if (key != null && value != null) {
ret = String.format(CUSTOM_ATTR_SEARCH_FORMAT, key, value);
} else {
ret = attrValue;
}
}
return ret;
}
private Predicate toInMemoryPredicate(AtlasStructType type, String attrName, SearchParameters.Operator op, String attrVal) {
Predicate ret = null;
......
......@@ -156,26 +156,26 @@ public class TestEntitiesREST {
@Test
public void testCustomAttributesSearch() throws Exception {
AtlasEntity dbWithCustomAttr = new AtlasEntity(dbEntity);
HashMap customAttr = new HashMap<String, String>() {{
put("key1", "value1");
}};
Map customAttr = new HashMap<String, String>() {{ put("key1", "value1"); }};
dbWithCustomAttr.setCustomAttributes(customAttr);
AtlasEntitiesWithExtInfo atlasEntitiesWithExtInfo = new AtlasEntitiesWithExtInfo(dbWithCustomAttr);
EntityMutationResponse response = entityREST.createOrUpdate(atlasEntitiesWithExtInfo);
EntityMutationResponse response = entityREST.createOrUpdate(atlasEntitiesWithExtInfo);
Assert.assertNotNull(response.getUpdatedEntitiesByTypeName(DATABASE_TYPE));
searchParameters = new SearchParameters();
searchParameters.setTypeName("_ALL_ENTITY_TYPES");
SearchParameters.FilterCriteria fc = new SearchParameters.FilterCriteria();
fc.setAttributeName(CUSTOM_ATTRIBUTES_PROPERTY_KEY);
fc.setOperator(SearchParameters.Operator.EQ);
fc.setAttributeValue("\"key1:value1\"");
SearchParameters.FilterCriteria filter = new SearchParameters.FilterCriteria();
searchParameters.setEntityFilters(fc);
filter.setAttributeName(CUSTOM_ATTRIBUTES_PROPERTY_KEY);
filter.setOperator(SearchParameters.Operator.CONTAINS);
filter.setAttributeValue("key1=value1");
searchParameters.setEntityFilters(filter);
AtlasSearchResult res = discoveryREST.searchWithParameters(searchParameters);
......
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