Table API¶
Note
The table API
is available in SLU v4.1 or later.
The table API
enables semantic search and allows users to search for information within JSON-formatted data using natural language queries.
The table API
utilizes table-based storage to store data provided to it and enables users to efficiently search for records within the table. The table API
goes beyond simple keyword matching and takes into account the semantic meaning of user queries. As a result, users can find the most relevant information even if they use different words or phrases to express their query.
The table api
can be beneficial in use cases when efficient and accurate data retrieval is required. For example, you can use the table API
to:
Search for products or items
Explore data
Analyze data and so on
To use the table API
, add the following logic to your dialog script:
Create a table, define the table columns and identify for which columns semantic search should be enabled. Tables are created within the AI assistant project scope. For one project, you can create several tables.
Use the
update()
method to populate the table with data. Define how table columns are mapped to keys of the JSON object from which data should be retrieved.Use the
commit()
method to commit the data to table.Use the
search()
method to run the query against the table records. Define the table column in which data should be searched, query to be executed, similarity score and maximum number of results to be returned.
Note
If you need to add table columns after the table has been created, update the tableName
as well.
Example of use¶
Here are a few examples of how you can use the Table API to search JSON data and show information in an aesthetic format:
Let’s assume you have a JSON-formatted list of products. You want the user to run a query against the product description and display a list of matching results in the Alan AI Chat. For this, you can add the following code to your dialog script:
let productList = [
{
"id": 1,
"name": "iPhone 13 Pro",
"min_price":"$999",
"vendor":"Apple",
"spec":"A15 Bionic chip, Super Retina XDR display, ProMotion technology, Triple 12MP camera system, 5G capability, Face ID, Ceramic Shield front cover, and Water and dust resistance.",
"productDetails": "Major upgrades over its predecessor include improved battery life, improved cameras and computational photography, rack focus for video in a new 'Cinematic Mode' at 1080p 30 fps, Apple ProRes video recording, a new A15 Bionic system on a chip, and a variable 10–120 Hz display, marketed as ProMotion.",
},
{
"id": 2,
"name": "Samsung Galaxy S21 Ultra",
"min_price":"$1,199",
"vendor":"Samsung",
"spec":"Exynos 2100 or Snapdragon 888 processor, Dynamic AMOLED 2X display, Quad HD+ resolution, 108MP quad camera system, 5G capability, In-display fingerprint sensor, S Pen support, and Water and dust resistance.",
"productDetails": "The Galaxy S21 Ultra comes in a sleeker design and offers faster performance from Qualcomm's Snapdragon 888 chip. And, unlike the regular Galaxy S21, you don't have to make nearly as many trade-offs. You get a better main 108MP camera, a glass back (instead of plastic), more RAM and a higher-res display.",
},
{
"id": 3,
"name": "Google Pixel 6 Pro",
"min_price":"$899",
"vendor":"Google",
"spec":"Google Tensor chip, 6.7-inch QHD+ OLED display, 50MP main camera, 12MP ultra-wide camera, 5G capability, Titan M2 security chip, In-display fingerprint sensor, and Android 12 operating system.",
"productDetails":"With its unique design and high-quality build, impressive display and good battery life, and its consistently good cameras and feature-rich software, the Google Pixel 6 Pro stands toe-to-toe with the very best from Apple and Samsung. This is the Google flagship we've been waiting for.",
},
];
// Create a table
let table = api.table_v1({
tableName: 'products',
columns: {id: 'str,unique', name: 'str', price: 'str', description: 'str,semantic', specification: 'str,semantic'}
});
// Populate the table
async function reloadTable() {
let products = productList;
for (let p of products) {
table.update({
id: p.id,
name: p.name,
price: p.min_price,
description: p.productDetails,
specification: p.spec
});
}
// Commit data
await table.commit();
setTimeout(reloadTable, 5000);
}
reloadTable();
// Search for data
intent(`Find a model with $(QUERY* .+)`, async p => {
let query = p.QUERY.value;
let products = await table.search({description: {q: query, score: 0.3, top_k: 3}});
if (products.length) {
p.play(`Here is a list of models you may like:`);
for (let product of products) {
p.play(`**Name**: ${product.name} \n\n **Price**: ${product.price} \n\n **Details**: ${product.description}`, opts({markdown:true, audio:false}));
}
} else {
p.play(`Nothing found`);
}
});
Here, the product details are saved to productList
. After that, you can use the table API
to retrieve a list of products matching the search query:
Create a table with the following parameters:
tableName: 'products'
columns: {id: 'str,unique', name: 'str', price: 'str', description: 'str,semantic', specification: 'str,semantic'}
Map table columns to JSON data keys with the
update()
method:id: p.id
name: p.name
price: p.min_price
description: p.productDetails
specification: p.spec
Commit data with the
commit()
method.Run a query against the
description
column of table records with thesearch()
method. In the example above, the similarity score is set to 0.3 and top 3 results are retrieved.Display the obtained results as separate cards in the Alan AI Chat.
Now, the user can run the following search queries against the products list:
Find a model with an enhanced camera
Find a model with improved battery life
Let’s assume you have a JSON-formatted list of incidents. You want the user to run a query against the incident description, format the incident data using the Generator API and display a list of results in the Alan AI Chat as a table. For this, you can add the following code to your dialog script:
let incidents = [
{
"id": 1,
"location": "123 Main Street",
"date": "2023-11-01",
"description": "A laptop was stolen from the office premises. The suspect is unknown."
},
{
"id": 2,
"location": "Company Server",
"date": "2023-10-15",
"description": "A cybersecurity breach was detected, leading to unauthorized access to sensitive data. The incident is under investigation."
},
{
"id": 3,
"location": "Warehouse",
"date": "2023-09-20",
"description": "Illegal drugs were found in a shipment during routine inspection. The authorities have been notified."
},
{
"id": 4,
"location": "456 Elm Street",
"date": "2023-08-05",
"description": "Several items were reported stolen from a company vehicle parked on Elm Street."
},
{
"id": 5,
"location": "Network Infrastructure",
"date": "2023-07-12",
"description": "A phishing attack was attempted on our network, but our security systems detected and prevented it."
},
{
"id": 6,
"location": "789 Oak Avenue",
"date": "2023-05-10",
"description": "Cash and company equipment were stolen from the Oak Avenue office during non-business hours."
}
]
// Create a table
let incidentsTable = api.table_v1({
tableName: 'incidents',
columns: {id: 'str,unique', location: 'str', date: 'str', description: 'str,semantic'}
});
// Populate the table
async function reloadTable() {
let data = incidents;
console.log(data);
for (let i of data) {
incidentsTable.update({
id: i.id,
location: i.location,
date: i.date,
description: i.description
});
}
// Commit data
await incidentsTable.commit();
setTimeout(reloadTable, 5000);
}
reloadTable();
// Define the report format for the Generator API
let generator = api.generator_v1({
format: 'markdown',
formatting: 'add a report header, use the table format, use bold highlighting for key entities such as id and location.'
});
// Search for data
intent(`(Find|Show|) $(QUERY* .+)`, async p=> {
let query = p.QUERY.value;
p.userData.incidents = await incidentsTable.search({description: {q: query, score: 0.3, top_k: 3}});
console.log(p.userData.incidents);
if (p.userData.incidents.length) {
p.play(`Here is a list of incidents:`);
// Generate a report in the table format
let instruct = "incidents";
let stream = generator.generate({data: p.userData.incidents, instruct});
p.play(stream);
let answer = await stream.gather();
console.log(answer.answer);
} else {
p.play(`Sorry, nothing found`);
}
});
Here, the incidents details are saved to incidents
variable. After that, you can use the table API
together with Generator API
to retrieve a list of incidents matching the search query and present them as a table in the chat:
Create a table with the following parameters:
tableName: 'incidents'
columns: {id: 'str,unique', location: 'str', date: 'str', description: 'str,semantic'}
Map table columns to JSON data keys with the
update()
method:id: i.id
location: i.location
date: i.date
description: i.description
Commit data with the
commit()
method.Run a query against the
description
column of table records with thesearch()
method. In the example above, the similarity score is set to 0.3 and top 3 results are retrieved.Display the results using the
Generator API
that formats the obtained data as a table.
Now, the user can run the following search queries against the incidents list:
Show incidents involving theft
Find incidents regarding unauthorized access
Note that even though words from the query are not present in the description, Alan AI analyzed the intent and true meaning behind the query to bring up the results.