Example - Index and query JSON documents
Learn how to use the Redis Query Engine with JSON
This example shows how to create a search index for JSON data and run queries against the index.
Make sure that you have Redis Stack and node-redis
installed.
Start by importing dependencies:
import {
createClient,
SchemaFieldTypes,
AggregateGroupByReducers,
AggregateSteps,
} from 'redis';
Connect to the database:
const client = await createClient();
await client.connect();
Create some test data to add to the database:
const user1 = {
name: 'Paul John',
email: 'paul.john@example.com',
age: 42,
city: 'London'
};
const user2 = {
name: 'Eden Zamir',
email: 'eden.zamir@example.com',
age: 29,
city: 'Tel Aviv'
};
const user3 = {
name: 'Paul Zamir',
email: 'paul.zamir@example.com',
age: 35,
city: 'Tel Aviv'
};
Create an index. In this example, only JSON documents with the key prefix user:
are indexed. For more information, see Query syntax.
await client.ft.create('idx:users', {
'$.name': {
type: SchemaFieldTypes.TEXT,
AS: 'name'
},
'$.city': {
type: SchemaFieldTypes.TEXT,
AS: 'city'
},
'$.age': {
type: SchemaFieldTypes.NUMERIC,
AS: 'age'
}
}, {
ON: 'JSON',
PREFIX: 'user:'
});
Add the three sets of user data to the database as
JSON objects.
If you use keys with the user:
prefix then Redis will index the
objects automatically as you add them. Note that placing
the commands in a Promise.all()
call is an easy way to create a
pipeline,
which is more efficient than sending the commands individually.
const [user1Reply, user2Reply, user3Reply] = await Promise.all([
client.json.set('user:1', '$', user1),
client.json.set('user:2', '$', user2),
client.json.set('user:3', '$', user3)
]);
You can now use the index to search the JSON objects. The
query
below searches for objects that have the text "Paul" in any field
and have an age
value in the range 30 to 40:
let findPaulResult = await client.ft.search('idx:users', 'Paul @age:[30 40]');
console.log(findPaulResult.total); // >>> 1
findPaulResult.documents.forEach(doc => {
console.log(`ID: ${doc.id}, name: ${doc.value.name}, age: ${doc.value.age}`);
});
Specify query options to return only the city
field:
let citiesResult = await client.ft.search('idx:users', '*',{
RETURN: 'city'
});
console.log(citiesResult.total); // >>> 3
citiesResult.documents.forEach(cityDoc => {
console.log(cityDoc.value);
});
Use an aggregation query to count all users in each city.
let aggResult = await client.ft.aggregate('idx:users', '*', {
STEPS: [{
type: AggregateSteps.GROUPBY,
properties: '@city',
REDUCE: [{
type: AggregateGroupByReducers.COUNT,
AS: 'count'
}]
}]
});
console.log(aggResult.total); // >>> 2
aggResult.results.forEach(result => {
console.log(`${result.city} - ${result.count}`);
});
Finally, close the connection to Redis.
await client.quit();
See the Redis Query Engine docs for a full description of all query features with examples.