private buildSearchTraverser()

in source/packages/services/assetlibrary/src/search/search.full.dao.ts [43:185]


    private buildSearchTraverser(
        conn: NeptuneConnection,
        request: SearchRequestModel,
        authorizedPaths: string[]
    ): process.GraphTraversal {
        logger.debug(
            `search.full.dao buildSearchTraverser: in: request: ${JSON.stringify(
                request
            )}, authorizedPaths:${authorizedPaths}`
        );

        let source: process.GraphTraversalSource = conn.traversal;
        if (this.enableDfeOptimization) {
            source = source.withSideEffect('Neptune#useDFE', true);
        }

        const ancestorId = `group___${request.ancestorPath}`;
        const traverser =
            request.ancestorPath && request.includeAncestor
                ? source
                      .V(ancestorId)
                      // Add the ancestor vertex to the emitted vertices
                      .union(__.repeat(__.in_().simplePath().dedup()).emit(), __.V(ancestorId))
                      .dedup()
                      .as('a')
                : request.ancestorPath
                ? source.V(ancestorId).repeat(__.in_().simplePath().dedup()).emit().as('a')
                : source.V().as('a');

        // construct Gremlin traverser from request parameters

        if (request.types !== undefined) {
            request.types.forEach((t) => traverser.select('a').hasLabel(t));
        }

        if (request.ntypes !== undefined) {
            request.ntypes.forEach((t) => traverser.select('a').not(__.hasLabel(t)));
        }

        if (request.eq !== undefined) {
            request.eq.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterVBase(f, traverser);
                traverser.has(f.field, f.value);
            });
        }
        if (request.neq !== undefined) {
            request.neq.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterVBase(f, traverser);
                traverser.not(__.has(f.field, f.value));
            });
        }
        if (request.lt !== undefined) {
            request.lt.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterVBase(f, traverser);
                traverser.has(f.field, process.P.lt(Number(f.value)));
            });
        }
        if (request.lte !== undefined) {
            request.lte.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterVBase(f, traverser);
                traverser.has(f.field, process.P.lte(Number(f.value)));
            });
        }
        if (request.gt !== undefined) {
            request.gt.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterVBase(f, traverser);
                traverser.has(f.field, process.P.gt(Number(f.value)));
            });
        }
        if (request.gte !== undefined) {
            request.gte.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterVBase(f, traverser);
                traverser.has(f.field, process.P.gte(Number(f.value)));
            });
        }
        if (request.startsWith !== undefined) {
            request.startsWith.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterVBase(f, traverser);
                traverser.has(f.field, process.TextP.startingWith(f.value));
            });
        }

        if (request.endsWith !== undefined) {
            request.endsWith.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterVBase(f, traverser);
                traverser.has(f.field, process.TextP.endingWith(f.value));
            });
        }

        if (request.contains !== undefined) {
            request.contains.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterVBase(f, traverser);
                traverser.has(f.field, process.TextP.containing(f.value));
            });
        }

        if (request.exists !== undefined) {
            request.exists.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterEBase(f, traverser);
                traverser.has(f.field, f.value);
            });
        }

        if (request.nexists !== undefined) {
            request.nexists.forEach((f) => {
                traverser.select('a');
                this.buildSearchFilterEBaseNegated(f, traverser, f.field, f.value);
            });
        }

        // if authz is enabled, only return results that the user is authorized to view
        if ((authorizedPaths?.length ?? 0) > 0) {
            // must reset all traversals so far as we need to use simplePath when FGAC is enabled to prevent cyclic checks
            traverser.select('a').dedup().fold().unfold().as('a');

            const authorizedPathIds = authorizedPaths.map((path) => `group___${path}`);
            traverser
                .local(
                    __.until(__.hasId(process.P.within(authorizedPathIds))).repeat(
                        __.outE().has('isAuthCheck', true).otherV().simplePath().dedup()
                    )
                )
                .as('authorization');
        }

        logger.debug(
            `search.full.dao buildSearchTraverser: traverser: ${JSON.stringify(
                traverser.toString()
            )}`
        );

        return traverser.select('a').dedup();
    }