UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

392 lines (389 loc) • 14.3 kB
import type SpatialReference from "../../geometry/SpatialReference.js"; import type GraphQuery from "./GraphQuery.js"; import type InputQuantizationParameters from "./InputQuantizationParameters.js"; import type OutputQuantizationParameters from "./OutputQuantizationParameters.js"; import type { GraphQueryProperties } from "./GraphQuery.js"; import type { ValidBindParameterType } from "./types.js"; import type { SpatialReferenceProperties } from "../../geometry/SpatialReference.js"; export interface GraphQueryStreamingProperties extends GraphQueryProperties, Partial<Pick<GraphQueryStreaming, "bindGeometryQuantizationParameters" | "bindParameters" | "outputQuantizationParameters" | "provenanceBehavior">> { /** * Custom output spatial reference parameters for output geometry. * Overrides the default lossless WGS84 quantization. */ outputSpatialReference?: SpatialReferenceProperties | null; } /** * Defines a streaming query operation performed on a [knowledge graph service's](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraphService/) * [graph](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/KnowledgeGraph/) resource. * The [entities](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/Entity/) and [relationships](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/Relationship/) * in the graph are queried by sending an Esri implementation of [openCypher](https://opencypher.org/) query. * * Streaming query returns [results](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/GraphQueryStreamingResult/) faster than query and in small chunks that can be processed immediately. * Streaming query also allows [bind parameters](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/GraphQueryStreaming/#bindParameters). * * @since 4.25 * @see [Sample - Query a knowledge graph](https://developers.arcgis.com/javascript/latest/sample-code/knowledgegraph-query/) * @see [knowledgeGraphService.executeQueryStreaming](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraphService/#executeSearchStreaming) * @example * // sample streaming query using bind parameters * // to search for entities with a the `name` property that matches a specific string * // or have their geometry within a bounding box. * // get all parts bought by each supplier. * // query returns both the supplier and the part it buys. * const query = `MATCH (s:Supplier)-[:buys_part]-(p:Part) * WHERE s.name=$name OR esri.graph.ST_Intersects($geom, s.geometry) * RETURN s,p`; * * KnowledgeGraphModule.executeQueryStreaming( * knowledgeGraph, * { * openCypherQuery: query, * bindParameters: { * name: "Supplier 1", * geom: new Polygon({ * rings: [ * [ * [-78, 38], * [-78, 39], * [-76, 39], * [-76, 38], * [-78, 38] * ], * ], * }), * } * }).then((streamingQueryResult)=>{ * // streaming query returns a readableStream which must be read to access the returned graph data * readStream(streamingQueryResult); * }) * @example * // a function to read the readable stream returned from the above query * const readStream = async (streamingQueryResult) => { * let time = Date.now(); * let reader = streamingQueryResult.resultRowsStream.getReader(); * try { * while (true) { * const { done, value } = await reader.read(); * if (done) { * console.log(`All records returned, stream closed: ${(Date.now() - time) / 1000} seconds`); * break; * } * console.log(`Streaming chunk returned in: ${(Date.now() - time) / 1000} seconds`, value); * // use the results * // list the parts bought by each supplier * let supplierParts = {}; * // each element of the result array will contain one supplier and one part it buys * for (var v in value){ * let supplier = value[v][0].properties.Name * let part = value [v][1].properties.Name * if(!(supplier in supplierParts)){ * supplierParts[supplier] = []; * } * // collect parts by supplier that buys them * supplierParts[supplier].push(part); * console.log(supplierParts); * // result printed to the console: {Supplier 1:[Part1], Supplier 3:[Part2, Part3]} * } * } * } catch (err) { * if (err.name === "AbortError") { * console.log("Request aborted as expected"); * } else { * throw err; * } * } * }; * @example * // result stream from above query after it has been read * "Streaming chunk returned in: 0.082 seconds" * [ * [{ * "declaredClass": "esri.rest.knowledgeGraph.Entity", * "properties": { * "Name": "Supplier 1", * "City": "Washington DC", * "EmployeeCount": 31 * }, * "typeName": "Supplier", * "id": "{57FDF2F3-34C8-48EF-9A3B-76ED9314C4D2}" * },{ * "declaredClass": "esri.rest.knowledgeGraph.Entity", * "properties": { * "Part_ID": 695401, * "Name": "Part1", * "Minimum_quantity": 360 * }, * "typeName": "Part", * "id": "{IWN51W4-1AW8-A2W6-1AW5F-1AW8F9F4W51AS}", * }], * [{ * "declaredClass": "esri.rest.knowledgeGraph.Entity", * "properties": { * "Name": "Supplier 2", * "City": "Baltimore", * "EmployeeCount": 53 * }, * "typeName": "Supplier", * "id": "{1A4W8F5W-1WA8-5W6A-A1W8-A1W5F8W3S482A}" * },{ * "declaredClass": "esri.rest.knowledgeGraph.Entity", * "properties": { * "Part_ID": 695401, * "Name": "Part2", * "Minimum_quantity": 2500 * }, * "typeName": "Part", * "id": "{A1W5F8W4F-A1W8-1894-16A5-A86WF4A8SFWD}", * }], * [{ * "declaredClass": "esri.rest.knowledgeGraph.Entity", * "properties": { * "Name": "Supplier 2", * "City": "Baltimore", * "EmployeeCount": 53 * }, * "typeName": "Supplier", * "id": "{1A4W8F5W-1WA8-5W6A-A1W8-L5H4G8RT1PK3}" * },{ * "declaredClass": "esri.rest.knowledgeGraph.Entity", * "properties": { * "Part_ID": 695401, * "Name": "Part3", * "Minimum_quantity": 5000 * }, * "typeName": "Part", * "id": "{PTJ51FT-KY4H-1GY5-G1Y8-G1Y5K49G8Y4GHJ}", * }] * ] * @example * // aborting the query * // create instance of native browser abort controller * const controller = new AbortController(); * // create query * KnowledgeGraphModule * .executeQueryStreaming( * knowledgeGraph, * { * openCypherQuery: "MATCH (n) RETURN n LIMIT 100", * }, * { * signal: controller.signal, * } * ) * .then((streamingQueryResult) => { * readStream(streamingQueryResult); * }) * // indicate that the stream was aborted * .catch((err) => { * if (err.name === "AbortError") { * console.log("Request aborted as expected"); * } * * // abort the query after half a second * setTimeout(() => { * console.log("Sending abort signal"); * controller.abort(); * }, 500); */ export default class GraphQueryStreaming extends GraphQuery { constructor(properties?: GraphQueryStreamingProperties); /** * Custom quantization parameters for input geometry that compresses geometry for transfer to the server. * Overrides the default lossless WGS84 quantization. * * @example * // sample implementation of an input quantization parameter * // query entities within a bounding box * const query = "MATCH (n) WHERE esri.graph.ST_Intersects($geom, n.geometry) RETURN n" * * KnowledgeGraphModule.executeQueryStreaming( * knowledgeGraph, * { * openCypherQuery: query, * bindParameters: { * param_filter_geom: new Polygon({ * rings: [ * [ * [-89, -89], * [89, -89], * [89, 89], * [-89, 89], * [-89, -89], * ], * ], * }), * }, * inputQuantizationParameters: { * xyResolution: 0.003, * xFalseOrigin: 25, * yFalseOrigin: 25, * zResolution: 1, * zFalseOrigin: 1, * mResolution: 1, * mFalseOrigin: 1, * }, * } * } * ); */ accessor bindGeometryQuantizationParameters: InputQuantizationParameters | null | undefined; /** * Specifies a set of parameters containing data to be included in the query. * * > [!WARNING] * > * > **Note** * > * > Check the service definition for the [knowledgeGraphService](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraphService/) * > for valid geometry types. Not all external graph stores will supported all geometry types. * * @example * // bind a polygon to search for entities withing a bounding box. * const query = "MATCH (n) WHERE esri.graph.ST_Intersects($geom, n.geometry) RETURN n"; * * KnowledgeGraphModule.executeQueryStreaming( * knowledgeGraph, * { * openCypherQuery: query, * bindParameters: { * geom: new Polygon({ * rings: [ * [ * [-89, -89], * [89, -89], * [89, 89], * [-89, 89], * [-89, -89], * ], * ], * }), * } * }).then((streamingQueryResult)=>{ * // streaming query returns a readableStream which must be read to access the returned graph data * readStream(streamingQueryResult); * }) * @example * // bind a list of ids * // get all relationships between suppliers and a select list of parts. * const query = "MATCH (s:Supplier)-[rel]-(p:Part) WHERE p.globalid IN $ids RETURN rel"; * * KnowledgeGraphModule.executeQueryStreaming( * knowledgeGraph, * { * openCypherQuery: query, * bindParameters: { * ids:[ * "{WIHPTR45-1RO5-9HY1-FK50-P1J5U8D1FER7}", * "{SSOE5G4O-T7T8-4G8Y-2RD1-P8D1A7G4S7EA}", * "{2SE8HE8D-81ES-9HY1-1SE8-OPAWON41869S}", * "{1SE8E6G8-5DT8-S8E1-6S8E-D8R4FJ8S8S1S}", * "{SE86I2BD-8R73-2SE8-6S8E-7R8DR86S4SD6}", * "{N2T8K52R-2SDE-1SEG-S8ES-6SE8HUKY6AIN}", * "{2AWAGP86-SESR-5SE8-4SE8-68RD66846SPL}", * ], * }), * } * }).then((streamingQueryResult)=>{ * // streaming query returns a readableStream which must be read to access the returned graph data * readStream(streamingQueryResult); * }) */ accessor bindParameters: Record<string, ValidBindParameterType> | null | undefined; /** * Used to project the geometry onto a virtual grid, likely representing * pixels on the screen. Geometry coordinates are converted to integers * by building a grid with a resolution matching the * [OutputQuantizationParameters.tolerance](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/OutputQuantizationParameters/#tolerance). * Each coordinate is then snapped to one pixel on the grid. * * @example * // sample implementation of an output quantization parameter * * // query entities within a bounding box. * const query = "MATCH (n) WHERE esri.graph.ST_Intersects($geom, n.geometry) RETURN n" * * KnowledgeGraphModule.executeQueryStreaming( * knowledgeGraph, * { * openCypherQuery: query, * bindParameters: { * geom: new Polygon({ * rings: [ * [ * [-89, -89], * [89, -89], * [89, 89], * [-89, 89], * [-89, -89], * ], * ], * }), * }, * outputQuantizationParameters: { * extent: { * xmax: 30, * xmin: 20, * ymax: 30, * ymin: 20, * }, * tolerance: 0.001, * quantizeMode: "view", * } * } * } * ); */ accessor outputQuantizationParameters: OutputQuantizationParameters | null | undefined; /** * Custom output spatial reference parameters for output geometry. * Overrides the default lossless WGS84 quantization. */ get outputSpatialReference(): SpatialReference | null | undefined; set outputSpatialReference(value: SpatialReferenceProperties | null | undefined); /** * Enables provenance to be used and returned in the query. * This will only be available if the service has [provenance enabled](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/ServiceDefinition/#supportsProvenance). * * @example * // query entities within a bounding box that have a specific provenance. * const query = "MATCH (n), (prov:Provenance) * WHERE esri.graph.ST_Intersects($geom, n.geometry) and prov.instanceID in $idList * RETURN n, prov" * * KnowledgeGraphModule.executeQueryStreaming( * knowledgeGraph, * { * openCypherQuery: query, * provenanceBehavior: "include", * bindParameters: { * idList: ['{59ACF2B8-1A28-4825-9228-E0CE1AFF184A}', * '{AFF1A752-1A28-4825-9228-EFFEE152184A}', * '{4825AABB-1A28-4825-9228-E0CE1AFF9712}'], * geom: new Polygon({ * rings: [ * [ * [-89, -89], * [89, -89], * [89, 89], * [-89, 89], * [-89, -89], * ], * ], * }), * }, * outputQuantizationParameters: { * extent: { * xmax: 30, * xmin: 20, * ymax: 30, * ymin: 20, * }, * tolerance: 0.001, * quantizeMode: "view", * } * } * ); */ accessor provenanceBehavior: GraphQueryStreamingProvenanceBehavior | null | undefined; } export type GraphQueryStreamingProvenanceBehavior = "exclude" | "include";