索引和查询文档

了解如何使用 Redis Query Engine 处理 JSON 和哈希文档。

此示例展示了如何为 JSON 文档创建搜索索引并针对该索引运行查询。然后,它继续展示了处理哈希文档的等效代码中的细微差异。

初始化

确保您已安装 Redis 开源版或其他 Redis 服务器。如果您尚未安装,请安装 node-redis 客户端库。

添加以下依赖项

import {
    createClient,
    SchemaFieldTypes,
    AggregateGroupByReducers,
    AggregateSteps,
} from 'redis';

创建数据

创建一些测试数据添加到您的数据库。下面显示的示例数据兼容 JSON 和哈希对象。

const user1 = {
    name: 'Paul John',
    email: '[email protected]',
    age: 42,
    city: 'London'
};

const user2 = {
    name: 'Eden Zamir',
    email: '[email protected]',
    age: 29,
    city: 'Tel Aviv'
};

const user3 = {
    name: 'Paul Zamir',
    email: '[email protected]',
    age: 35,
    city: 'Tel Aviv'
};

添加索引

连接到您的 Redis 数据库。下面的代码展示了最基本的连接方式,但请参阅连接到服务器以了解更多可用的连接选项。

const client = await createClient();
await client.connect();

创建索引。在此示例中,仅索引键前缀为 user: 的 JSON 文档。有关更多信息,请参阅查询语法

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:'
});

添加数据

将三组用户数据作为 JSON 对象添加到数据库中。如果您使用键前缀为 user: 的键,Redis 将在您添加对象时自动对其进行索引。请注意,将命令放在 Promise.all() 调用中是创建管道的一种简单方式,这比单独发送命令更高效。

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)
]);

查询数据

现在您可以使用索引来搜索 JSON 对象。下面的查询搜索在任何字段中包含文本“Paul”且 age 值在 30 到 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}`);
});

指定查询选项以仅返回 city 字段

let citiesResult = await client.ft.search('idx:users', '*',{
    RETURN: 'city'
});

console.log(citiesResult.total); // >>> 3

citiesResult.documents.forEach(cityDoc => {
    console.log(cityDoc.value);
});

使用聚合查询统计每个城市的用户数。

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}`);
});

最后,关闭与 Redis 的连接。

await client.quit();

与哈希文档的区别

哈希文档的索引与 JSON 索引非常相似,但您需要指定一些略微不同的选项。

为哈希索引创建模式时,您无需为字段添加别名,因为无论如何您都使用基本名称来访问字段。此外,在创建索引时,必须为 ON 选项使用 HASH。下面的代码展示了这些更改,使用了一个名为 hash-idx:users 的新索引,它与前面示例中用于 JSON 文档的 idx:users 索引相同。

await client.ft.create('hash-idx:users', {
    'name': {
        type: SchemaFieldTypes.TEXT
    },
    'city': {
        type: SchemaFieldTypes.TEXT
    },
    'age': {
        type: SchemaFieldTypes.NUMERIC
    }
}, {
    ON: 'HASH',
    PREFIX: 'huser:'
});

您使用 hSet() 添加哈希文档,而不是 json.set(),但相同的扁平 userX 对象对于哈希和 JSON 同样适用

const [huser1Reply, huser2Reply, huser3Reply] = await Promise.all([
    client.hSet('huser:1', user1),
    client.hSet('huser:2', user2),
    client.hSet('huser:3', user3)
]);

这里的查询命令对于哈希与对于 JSON 的工作方式相同(但哈希索引的名称不同)。结果的格式也相同

let findPaulHashResult = await client.ft.search(
    'hash-idx:users', 'Paul @age:[30 40]'
);

console.log(findPaulHashResult.total); // >>> 1

findPaulHashResult.documents.forEach(doc => {
    console.log(`ID: ${doc.id}, name: ${doc.value.name}, age: ${doc.value.age}`);
});
// >>> ID: huser:3, name: Paul Zamir, age: 35

更多信息

请参阅Redis Query Engine 文档,了解所有查询功能的完整说明和示例。

评价此页
返回顶部 ↑