Search 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 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.

sample-data-model

Good search terms include states abbreviations (e.g. CA, WA), countries, parks, and bumble bee descriptors (e.g. fuzzy, yellow, spotted).

Jump to how it works

For additional information on working with knowledge graph services see:

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: viewer01 password: I68VGU^nMurF.

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.

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.

search-types

For basic search or a streaming search with no additional parameters, run the 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.

stream-start-index
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 maxRecordCount parameter in the serviceDefinition of the knowledge graph. If the maxRecordCount is reached, then it will return all results up to that limit.

stream-max-records

Limit the search to specific entity or relationship types. Any number of types can be specified. All types are searched by default.

stream-type-filter

Limit the search to specific record ids. Any number of ids can be specified. All ids are searched by default.

stream-ids-filter
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.

stream-context

Run the search-btn or stream-btn .

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.

search-results

How it Works

Both search options require a connection 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
/**
* 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 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 typeCategoryFilter. Not all services support both.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 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 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.

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
/**
* 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.

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
// 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;
    }
  }
};

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