Query Knowledge Graphs

Note: Sign in to access the data in this sample. username: viewer01 password: I68VGU^nMurF

Getting Started

A knowledge graph allows you work with a graph network. This network connects people, places, and things (represented by entities) with each other through relationships that define how they are associated. Both entities and relationships can have associated properties.
An entity with a spatial location can be connected with other entities that do not have a spatial location.

This sample demonstrates the two methods for querying a knowledge graph: executeQuery() and executeQueryStreaming(). Both query and streaming query use an an Esri implementation of openCypher to find patterns in graph data.

The sample dataset contains observations of bumble bees made at locations around the United States. Each observation was made and verified by users and is of a specific species of bumble bee.

sample-data-model

Jump to how it works

For additional information on working with knowledge graph services see:

How to use this sample

Sign in

The data in this example is secured, as most knowledge graph data will be since the ArcGIS Knowledge Graph Server license is required. Therefore, the first step is to sign in to load the data.

In this sample sign in with the following credentials: username: viewer01 password: I68VGU^nMurF.

After signing in, the results section will update with the data model and service definition of the knowledge graph.

Query

The query defines the graph pattern to match. This pattern is a traversal of entity types and relationships that connect them. In this sample, the default pattern is to match any entities of the type user that are related to Observation entities through an observed or reviewed relationship. The relationship direction specifies that we are only interested in relationships going from User to Observation. The next part of the query is any conditions to apply to the pattern. The condition can be on any property of the entities or relationships in the pattern. In this example we are only interested in the Observation entities and their related users within a specific geographic area.

The streaming query accepts optional bind parameters as variables in the query string. Bind parameters specify a set of data to be included in the query. They are particularly helpful when trying to execute a query with a very large argument, such as a large set of IDs or intersecting a complex geometry. The geometry can be defined separately and included in the query with a variable.

streaming-query

To use a geometry bind parameter, the entity type in the where clause must contain the shape property (indicating it is a spatial entity). In this knowledge graph, the Observation entity type is the only spatial entity type.

This query returns the users who made or verified observations within the bounding polygon. The map provides the polygon to use in the spatial query. Change the location or size of the polygon to modify the query results.

bind-geom

See bindParameters for more information.

Note: ArcGIS Knowledge does not support all aspects of the openCypher query language. For example, queries can't be used to update the knowledge graph, only to return values. See Write an openCypher query for more on working with openCypher and knowledge graphs.

How it Works

The first step is to connect to a knowledge graph using fetchKnowledgeGraph.

Use dark colors for code blocksCopy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307  // set knowledge graph with url to service  const url =  "https://sampleserver7.arcgisonline.com/server/rest/services/Hosted/BumbleBees/KnowledgeGraphServer";  const knowledgeGraph = await KGModule.fetchKnowledgeGraph(url); 

Streaming query returns results in small chunks allowing the client to begin processing the data returned immediately rather than waiting for the entire result set to be returned before processing. Streaming is faster, more efficient, and will retrieve all matching records, even if the total exceeds query limits set in the service definition. Another benefit of streaming is that the request is encoded which means that it is far smaller than a traditional HTTP GET or JSON POST body. This is especially important when trying to do a query on a very large argument, such as a large set of IDs or intersecting a complex geometry. In this example the query returns users who have made or verified observations of bumblebees within a specific geographic area and generates a link chart showing how they are connected. This geographic area is denoted by a variable in the query string, with the geometry defining the area attached to the query through a bind parameter. MATCH (A:User) - [R:Observed | Reviewed] -> (B:Observation) WHERE esri.graph.ST_Intersects($userGeometry, B.shape) RETURN A LIMIT 10

Use dark colors for code blocksCopy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307  /**  * Streaming query to return the the selected entities or relationships that match the pattern defined in the query.  * It uses the bindParameter property to either bind geometry from the sketch on the map to the query to perform a spatial query on the graph  * or to bind a list of ids to query within.  * Streaming query has more options to refine the query results.  * Streaming query also has much higher performance when working with large datasets.  * It returns the data in chunks that can be processed as they are returned.  */  const executeQuery = async () => {  const bindParameters = {};  //create a geometry from the sketch layer as the bind parameter  const rings = [];   for (const graphic of graphicsLayer.graphics.items) {  //convert the geometry to wgs84 if necessary  const geom = graphic.geometry.spatialReference.isWGS84  ? graphic.geometry  : webMercatorUtils.webMercatorToGeographic(graphic.geometry);  rings.push(geom.rings[0]);  }   bindParameters["userGeometry"] = new Polygon({ rings: rings });  //execute the query and display the results  const queryResults = await KGModule.executeQueryStreaming(knowledgeGraph, {  openCypherQuery: "MATCH path=(A:User) - [] -> (B:Observation) WHERE esri.graph.ST_Intersects($userGeometry, B.shape) RETURN path",  bindParameters: bindParameters,  });  newLayer = true  readStream(queryResults);  } 

Each chunk returned by a streaming query is a readable stream that must be read before the results can be used. After the chunk is read it can be used in other client side processing. In this case it is used to add records to a link chart to show the relationships between the users who made or reviewed the observations in the areas of interest.

Use dark colors for code blocksCopy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307  // a function to read the stream returned from the streaming search  const readStream = async (streamingQueryResult, method) => {  //create the reader  let reader = streamingQueryResult.resultRowsStream.getReader();  let resultRows = []  //try to read the stream  try {  while (true) {  //read the stream  const { done, value } = await reader.read();  //stop reader when the stream is done  if (done) {  break;  }   updateLinkChart(value)  newLayer = false  //create the output list from the read stream.  }  // if there is an error in returning the stream or the stream is aborted  } catch (err) {  if (err.name === "AbortError") {  console.log("Request aborted as expected");  } else {  throw err;  }  }  }; 

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.