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();
}