Search in sources :

Example 26 with AtlasSearchResult

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);
}
Also used : AtlasFullTextResult(org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult) MultivaluedMapImpl(com.sun.jersey.core.util.MultivaluedMapImpl) AtlasSearchResult(org.apache.atlas.model.discovery.AtlasSearchResult) Test(org.testng.annotations.Test)

Example 27 with AtlasSearchResult

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());
}
Also used : AtlasEntityHeader(org.apache.atlas.model.instance.AtlasEntityHeader) AtlasSearchResult(org.apache.atlas.model.discovery.AtlasSearchResult) Test(org.testng.annotations.Test)

Example 28 with AtlasSearchResult

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;
}
Also used : AtlasObjectIdType(org.apache.atlas.type.AtlasBuiltInTypes.AtlasObjectIdType) AtlasObjectId(org.apache.atlas.model.instance.AtlasObjectId) AtlasSearchResult(org.apache.atlas.model.discovery.AtlasSearchResult) AtlasAttribute(org.apache.atlas.type.AtlasStructType.AtlasAttribute) AtlasVertex(org.apache.atlas.repository.graphdb.AtlasVertex) AtlasEntityHeader(org.apache.atlas.model.instance.AtlasEntityHeader) GraphTransaction(org.apache.atlas.annotation.GraphTransaction)

Example 29 with AtlasSearchResult

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;
}
Also used : QueryParams(org.apache.atlas.query.QueryParams) AtlasIndexQuery(org.apache.atlas.repository.graphdb.AtlasIndexQuery) AtlasSearchResult(org.apache.atlas.model.discovery.AtlasSearchResult) GraphTransaction(org.apache.atlas.annotation.GraphTransaction)

Example 30 with AtlasSearchResult

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;
}
Also used : ScriptEngine(javax.script.ScriptEngine) AtlasSearchResult(org.apache.atlas.model.discovery.AtlasSearchResult) AtlasFullTextResult(org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult) AtlasSearchResult(org.apache.atlas.model.discovery.AtlasSearchResult) Result(org.apache.atlas.repository.graphdb.AtlasIndexQuery.Result) AttributeSearchResult(org.apache.atlas.model.discovery.AtlasSearchResult.AttributeSearchResult) AtlasAttribute(org.apache.atlas.type.AtlasStructType.AtlasAttribute) ScriptException(javax.script.ScriptException) AtlasBaseException(org.apache.atlas.exception.AtlasBaseException) AtlasVertex(org.apache.atlas.repository.graphdb.AtlasVertex) AtlasEntityHeader(org.apache.atlas.model.instance.AtlasEntityHeader) QueryParams(org.apache.atlas.query.QueryParams) GraphTransaction(org.apache.atlas.annotation.GraphTransaction)

Aggregations

AtlasSearchResult (org.apache.atlas.model.discovery.AtlasSearchResult)30 AtlasEntityHeader (org.apache.atlas.model.instance.AtlasEntityHeader)13 Test (org.testng.annotations.Test)13 GraphTransaction (org.apache.atlas.annotation.GraphTransaction)9 QueryParams (org.apache.atlas.query.QueryParams)8 AtlasVertex (org.apache.atlas.repository.graphdb.AtlasVertex)7 AtlasFullTextResult (org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult)6 AtlasBaseException (org.apache.atlas.exception.AtlasBaseException)5 AtlasAttribute (org.apache.atlas.type.AtlasStructType.AtlasAttribute)5 AttributeSearchResult (org.apache.atlas.model.discovery.AtlasSearchResult.AttributeSearchResult)4 ScriptEngine (javax.script.ScriptEngine)3 ScriptException (javax.script.ScriptException)3 AtlasServiceException (org.apache.atlas.AtlasServiceException)3 AtlasEntityType (org.apache.atlas.type.AtlasEntityType)3 MultivaluedMapImpl (com.sun.jersey.core.util.MultivaluedMapImpl)2 IOException (java.io.IOException)2 Consumes (javax.ws.rs.Consumes)2 GET (javax.ws.rs.GET)2 Path (javax.ws.rs.Path)2 Produces (javax.ws.rs.Produces)2