use of org.apache.atlas.model.discovery.AtlasSearchResult in project incubator-atlas by apache.
the class EntityDiscoveryJerseyResourceIT method testSearchUsingFullText.
@Test(dependsOnMethods = "testSearchDSLLimits")
public void testSearchUsingFullText() throws Exception {
AtlasSearchResult searchResult = atlasClientV2.fullTextSearchWithParams(dbName, 10, 0);
assertNotNull(searchResult);
assertEquals(searchResult.getQueryText(), dbName);
assertEquals(searchResult.getQueryType(), AtlasQueryType.FULL_TEXT);
List<AtlasFullTextResult> fullTextResults = searchResult.getFullTextResult();
assertEquals(fullTextResults.size(), 1);
AtlasFullTextResult result = fullTextResults.get(0);
assertNotNull(result.getEntity());
assertEquals(result.getEntity().getTypeName(), DATABASE_TYPE_BUILTIN);
assertNotNull(result.getScore());
// API works without limit and offset
String query = dbName;
MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
queryParams.add("query", query);
searchResult = atlasClientV2.fullTextSearch(query);
assertNotNull(searchResult);
assertEquals(searchResult.getFullTextResult().size(), 1);
// verify passed in limits and offsets are used
// higher limit and 0 offset returns all results
searchResult = atlasClientV2.fullTextSearchWithParams(query, 10, 0);
assertEquals(searchResult.getFullTextResult().size(), 1);
// offset is used
searchResult = atlasClientV2.fullTextSearchWithParams(query, 10, 1);
assertEquals(searchResult.getFullTextResult().size(), 1);
// limit is used
searchResult = atlasClientV2.fullTextSearchWithParams(query, 1, 0);
assertEquals(searchResult.getFullTextResult().size(), 1);
// higher offset returns 0 results
searchResult = atlasClientV2.fullTextSearchWithParams(query, 1, 2);
assertEquals(searchResult.getFullTextResult().size(), 1);
}
use of org.apache.atlas.model.discovery.AtlasSearchResult in project incubator-atlas by apache.
the class EntityDiscoveryJerseyResourceIT method testSearchUsingDSL.
@Test
public void testSearchUsingDSL() throws Exception {
String query = "from " + DATABASE_TYPE_BUILTIN + " " + QUALIFIED_NAME + "=\"" + dbName + "\"";
AtlasSearchResult searchResult = atlasClientV2.dslSearch(query);
assertNotNull(searchResult);
assertEquals(searchResult.getQueryText(), query);
assertEquals(searchResult.getQueryType(), AtlasQueryType.DSL);
List<AtlasEntityHeader> entities = searchResult.getEntities();
assertNotNull(entities);
assertEquals(entities.size(), 1);
AtlasEntityHeader dbEntity = entities.get(0);
assertEquals(dbEntity.getTypeName(), DATABASE_TYPE_BUILTIN);
assertEquals(dbEntity.getDisplayText(), dbName);
assertEquals(dbEntity.getStatus(), Status.ACTIVE);
assertNotNull(dbEntity.getGuid());
assertNull(searchResult.getAttributes());
assertNull(searchResult.getFullTextResult());
}
use of org.apache.atlas.model.discovery.AtlasSearchResult in project incubator-atlas by apache.
the class EntityDiscoveryService method searchWithParameters.
@Override
@GraphTransaction
public AtlasSearchResult searchWithParameters(SearchParameters searchParameters) throws AtlasBaseException {
AtlasSearchResult ret = new AtlasSearchResult(searchParameters);
SearchContext context = new SearchContext(searchParameters, typeRegistry, graph, indexer.getVertexIndexKeys());
// For future cancellations
String searchID = searchTracker.add(context);
try {
List<AtlasVertex> resultList = context.getSearchProcessor().execute();
// By default any attribute that shows up in the search parameter should be sent back in the response
// If additional values are requested then the entityAttributes will be a superset of the all search attributes
// and the explicitly requested attribute(s)
Set<String> resultAttributes = new HashSet<>();
Set<String> entityAttributes = new HashSet<>();
if (CollectionUtils.isNotEmpty(searchParameters.getAttributes())) {
resultAttributes.addAll(searchParameters.getAttributes());
}
if (CollectionUtils.isNotEmpty(context.getEntityAttributes())) {
resultAttributes.addAll(context.getEntityAttributes());
}
for (String resultAttribute : resultAttributes) {
AtlasAttribute attribute = context.getEntityType().getAttribute(resultAttribute);
if (attribute != null) {
AtlasType attributeType = attribute.getAttributeType();
if (attributeType instanceof AtlasArrayType) {
attributeType = ((AtlasArrayType) attributeType).getElementType();
}
if (attributeType instanceof AtlasEntityType || attributeType instanceof AtlasObjectIdType) {
entityAttributes.add(resultAttribute);
}
}
}
for (AtlasVertex atlasVertex : resultList) {
AtlasEntityHeader entity = entityRetriever.toAtlasEntityHeader(atlasVertex, resultAttributes);
ret.addEntity(entity);
// populate ret.referredEntities
for (String entityAttribute : entityAttributes) {
Object attrValue = entity.getAttribute(entityAttribute);
if (attrValue instanceof AtlasObjectId) {
AtlasObjectId objId = (AtlasObjectId) attrValue;
if (ret.getReferredEntities() == null) {
ret.setReferredEntities(new HashMap<String, AtlasEntityHeader>());
}
if (!ret.getReferredEntities().containsKey(objId.getGuid())) {
ret.getReferredEntities().put(objId.getGuid(), entityRetriever.toAtlasEntityHeader(objId.getGuid()));
}
} else if (attrValue instanceof Collection) {
Collection objIds = (Collection) attrValue;
for (Object obj : objIds) {
if (obj instanceof AtlasObjectId) {
AtlasObjectId objId = (AtlasObjectId) obj;
if (ret.getReferredEntities() == null) {
ret.setReferredEntities(new HashMap<String, AtlasEntityHeader>());
}
if (!ret.getReferredEntities().containsKey(objId.getGuid())) {
ret.getReferredEntities().put(objId.getGuid(), entityRetriever.toAtlasEntityHeader(objId.getGuid()));
}
}
}
}
}
}
} finally {
searchTracker.remove(searchID);
}
return ret;
}
use of org.apache.atlas.model.discovery.AtlasSearchResult in project incubator-atlas by apache.
the class EntityDiscoveryService method searchUsingFullTextQuery.
@Override
@GraphTransaction
public AtlasSearchResult searchUsingFullTextQuery(String fullTextQuery, boolean excludeDeletedEntities, int limit, int offset) throws AtlasBaseException {
AtlasSearchResult ret = new AtlasSearchResult(fullTextQuery, AtlasQueryType.FULL_TEXT);
QueryParams params = validateSearchParams(limit, offset);
AtlasIndexQuery idxQuery = toAtlasIndexQuery(fullTextQuery);
if (LOG.isDebugEnabled()) {
LOG.debug("Executing Full text query: {}", fullTextQuery);
}
ret.setFullTextResult(getIndexQueryResults(idxQuery, params, excludeDeletedEntities));
return ret;
}
use of org.apache.atlas.model.discovery.AtlasSearchResult in project incubator-atlas by apache.
the class EntityDiscoveryService method searchUsingBasicQuery.
@Override
@GraphTransaction
public AtlasSearchResult searchUsingBasicQuery(String query, String typeName, String classification, String attrName, String attrValuePrefix, boolean excludeDeletedEntities, int limit, int offset) throws AtlasBaseException {
AtlasSearchResult ret = new AtlasSearchResult(AtlasQueryType.BASIC);
if (LOG.isDebugEnabled()) {
LOG.debug("Executing basic search query: {} with type: {} and classification: {}", query, typeName, classification);
}
final QueryParams params = validateSearchParams(limit, offset);
Set<String> typeNames = null;
Set<String> classificationNames = null;
String attrQualifiedName = null;
if (StringUtils.isNotEmpty(typeName)) {
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName);
if (entityType == null) {
throw new AtlasBaseException(UNKNOWN_TYPENAME, typeName);
}
typeNames = entityType.getTypeAndAllSubTypes();
ret.setType(typeName);
}
if (StringUtils.isNotEmpty(classification)) {
AtlasClassificationType classificationType = typeRegistry.getClassificationTypeByName(classification);
if (classificationType == null) {
throw new AtlasBaseException(CLASSIFICATION_NOT_FOUND, classification);
}
classificationNames = classificationType.getTypeAndAllSubTypes();
ret.setClassification(classification);
}
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);
}
}
// results in a faster and accurate results than using CONTAINS/CONTAINS_PREFIX filter on entityText property
if (StringUtils.isNotEmpty(query)) {
final String idxQuery = getQueryForFullTextSearch(query, typeName, classification);
final int startIdx = params.offset();
final int resultSize = params.limit();
int resultIdx = 0;
for (int indexQueryOffset = 0; ; indexQueryOffset += getMaxResultSetSize()) {
final Iterator<Result<?, ?>> qryResult = graph.indexQuery(Constants.FULLTEXT_INDEX, idxQuery, indexQueryOffset).vertices();
if (LOG.isDebugEnabled()) {
LOG.debug("indexQuery: query=" + idxQuery + "; offset=" + indexQueryOffset);
}
if (!qryResult.hasNext()) {
break;
}
while (qryResult.hasNext()) {
AtlasVertex<?, ?> vertex = qryResult.next().getVertex();
String vertexTypeName = GraphHelper.getTypeName(vertex);
// skip non-entity vertices
if (StringUtils.isEmpty(vertexTypeName) || StringUtils.isEmpty(GraphHelper.getGuid(vertex))) {
continue;
}
if (typeNames != null && !typeNames.contains(vertexTypeName)) {
continue;
}
if (classificationNames != null) {
List<String> traitNames = GraphHelper.getTraitNames(vertex);
if (CollectionUtils.isEmpty(traitNames) || !CollectionUtils.containsAny(classificationNames, traitNames)) {
continue;
}
}
if (isAttributeSearch) {
String vertexAttrValue = vertex.getProperty(attrQualifiedName, String.class);
if (StringUtils.isNotEmpty(vertexAttrValue) && !vertexAttrValue.startsWith(attrValuePrefix)) {
continue;
}
}
if (skipDeletedEntities(excludeDeletedEntities, vertex)) {
continue;
}
resultIdx++;
if (resultIdx <= startIdx) {
continue;
}
AtlasEntityHeader header = entityRetriever.toAtlasEntityHeader(vertex);
ret.addEntity(header);
if (ret.getEntities().size() == resultSize) {
break;
}
}
if (ret.getEntities() != null && ret.getEntities().size() == resultSize) {
break;
}
}
} else {
final Map<String, Object> bindings = new HashMap<>();
String basicQuery = "g.V()";
if (classificationNames != null) {
bindings.put("traitNames", classificationNames);
basicQuery += gremlinQueryProvider.getQuery(AtlasGremlinQuery.BASIC_SEARCH_CLASSIFICATION_FILTER);
}
if (typeNames != null) {
bindings.put("typeNames", typeNames);
basicQuery += gremlinQueryProvider.getQuery(AtlasGremlinQuery.BASIC_SEARCH_TYPE_FILTER);
}
if (excludeDeletedEntities) {
bindings.put("state", Status.ACTIVE.toString());
basicQuery += gremlinQueryProvider.getQuery(AtlasGremlinQuery.BASIC_SEARCH_STATE_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());
basicQuery += gremlinQueryProvider.getQuery(AtlasGremlinQuery.TO_RANGE_LIST);
ScriptEngine scriptEngine = graph.getGremlinScriptEngine();
try {
Object result = graph.executeGremlinScript(scriptEngine, bindings, basicQuery, false);
if (result instanceof List && CollectionUtils.isNotEmpty((List) result)) {
List queryResult = (List) result;
Object firstElement = queryResult.get(0);
if (firstElement instanceof AtlasVertex) {
for (Object element : queryResult) {
if (element instanceof AtlasVertex) {
ret.addEntity(entityRetriever.toAtlasEntityHeader((AtlasVertex) element));
} else {
LOG.warn("searchUsingBasicQuery({}): expected an AtlasVertex; found unexpected entry in result {}", basicQuery, element);
}
}
}
}
} catch (ScriptException e) {
throw new AtlasBaseException(DISCOVERY_QUERY_FAILED, basicQuery);
} finally {
graph.releaseGremlinScriptEngine(scriptEngine);
}
}
return ret;
}
Aggregations