Note: Sign in to access the data in this sample. username
password
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 searching a knowledge graph: executeSearch() and executeSearchStreaming().
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.
Good search terms include states abbreviations (e.g. CA, WA), countries, parks, and bumble bee descriptors (e.g. fuzzy, yellow, spotted).
For additional information on working with knowledge graph services see:
- Introduction to Knowledge Graph in the JavaScript Maps SDK.
- Working with knowledge graph layers
- Query a knowledge graph
- Edit knowledge graph data
- Get started with ArcGIS Knowledge Server for overview of ArcGIS Knowledge for ArcGIS Enterprise.
- Hosted Knowledge Graph Service for information on managing knowledge graph services via ArcGIS Enterprise and the REST API.
- Get started with ArcGIS Knowledge (ArcGIS Pro) for information on ArcGIS Knowledge in ArcGIS Pro.
How to use this sample
1. 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
password
.
2. Enter search term
Enter a search term. The default search term is "bombus" (Latin name for the genus bumble bee) but you can provide any search term.
3. Specify Parameters
Specify whether to search for the term just in the properties of entities, just in the properties of relationships, or in the properties of both.
For basic search or a streaming search with no additional parameters, run the search.
Optional properties for streaming search
Streaming search has the following optional properties.
a. Start index
The record index to start the search. All records before this index will be ignored.
b. Maximum number of records
The maximum number of records to return from the search. By default this is not specified so all results will be
returned unless the number of results exceeds the max
parameter in the service
of the knowledge graph.
If the max
is reached, then it will return all results up to that limit.
c. Named types to search
Limit the search to specific entity or relationship types. Any number of types can be specified. All types are searched by default.
d. IDs to search
Limit the search to specific record ids. Any number of ids can be specified. All ids are searched by default.
e. Return search context
If checked, the the IDs of objects that match the search, the names of the properties that matched the search term, and the scores and highlights of the result set are returned.
4. Run the search
Run the or .
The search may take a few seconds to return results. The results will be displayed in the format that they are returned from the knowledge graph. The first result will be expanded to illustrate the structure of the returned result object.
How it Works
Both search options require a connection to a knowledge graph using fetchKnowledgeGraph.
/**
* Initialization function that connects to a knowledge graph and displays the data model and service definition.
* The data model is used to populate the dropdowns in the search with the correct named types and IDs.
*/
require([
"esri/rest/knowledgeGraphService",
], (KGModule ) => {
//url to the knowledge graph server
const url = "https://sampleserver7.arcgisonline.com/server/rest/services/Hosted/BumbleBees/KnowledgeGraphServer"
const init = async () => {
//get the knowledge graph data model and service definition.
knowledgeGraph = await KGModule.fetchKnowledgeGraph(url);
//display the data model and service definition for the knowledge graph
dataDiv.innerHTML = `<h3>Knowledge Graph</h3><calcite-tree>${buildList(knowledgeGraph, false,true)}</calcite-tree>`;
}
init()
...
)
Search
Search allows you to run a free text search against the knowledge graph.
The search can be limited to entity
, relationship
, or both
.
Note: Use fetchKnowledgeGraph() to
check the knowledge graph service definition
for valid values of type
. Not all services support both
.
/**
* Basic search to return any information related to the search term.
* Search is limited by the maxRecordCount parameter in the serviceDefinition of the graph.
*/
document
.getElementById('search-button').addEventListener('click', async (e) => {
const searchString = document.getElementById("search-keyword").value
const typeFilter = document.getElementById("search-type-filter").value
// execute search
const searchResults = await KGModule.executeSearch(knowledgeGraph, {
searchQuery: searchString,
typeCategoryFilter: typeFilter
})
// display results
const html = buildList(searchResults.resultRows, false, true)
dataDiv.innerHTML = `<h3>Search Results</h3><calcite-tree>${html}</calcite-tree>`;
})
Streaming Search
Streaming search 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 the search 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.
/**
* Streaming search to return the specified number of entities or relationships (or both)
* that contain the search term starting at the specified index.
* It will only search the named types specified or the ids specified.
* If neither are specified, it will search the entire graph.
* Streaming search has more options to refine the search results.
* Streaming search also has much higher performance when working with large datasets.
* It returns the data in chunks that can be processed as they are returned.
*/
document
.getElementById('streaming-search-button').addEventListener('click', async (e) => {
dataDiv.innerHTML = '';
const searchString = document.getElementById("streaming-search-keyword").value
const typeFilter = document.getElementById("streaming-search-type-filter").value
const namedTypes = document.getElementById("streaming-search-named-types").value
const index = document.getElementById("streaming-search-start-index").value
const limit = document.getElementById("streaming-search-limit").value
const ids = document.getElementById("streaming-search-ids").value
const context = document.getElementById('streaming-search-context').checked
//construct the search object
const searchParams = {
searchQuery: searchString,
typeCategoryFilter: typeFilter,
returnSearchContext: context,
}
if (index) { searchParams["start"] = index };
if (limit) { searchParams["num"] = limit };
if (namedTypes) { searchParams["namedTypesFilter"] = namedTypes };
if (ids) { searchParams["idsFilter"] = ids };
//execute the search and read the result
const searchResults = await KGModule.executeSearchStreaming(knowledgeGraph, searchParams)
readStream(searchResults);
})
Each chunk returned by a streaming search 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 create an HTML display of the result.
// a function to read the stream returned from the streaming search
const readStream = async (streamingQueryResult, method) => {
//create the reader
let reader = streamingQueryResult.resultRowsStream.getReader();
//try to read the stream
try {
while (true) {
//read the stream
const { done, value } = await reader.read();
//create the output list from the read stream.
dataDiv.innerHTML += `<h3>Search Results</h3><calcite-tree>${buildList(value, false, true)}</calcite-tree>`
//stop reader when the stream is done
if (done) {
break;
}
}
// 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;
}
}
};