I have the hash data pushed to redis and I want to apply group by on the data and get the results
Assume I have the following data on redis as Hash with the key '3801'
HSET "3801:1" username "albert" pids "11,12"
HSET "3801:2" username "bob" pids "11,12"
HSET "3801:3" username "casey" pids "13,14"
HSET "3801:4" username "david" pids "13"
I want to create index and group them based on pids. So, when I pass the input as 3801, I need the following as result (within the key)
albert,bob
casey
david
Redis Create Command:
FT.CREATE 3801:idx ON HASH PREFIX 1 3801: SCHEMA username TEXT SORTABLE pids TEXT SORTABLE
Redis Aggregate Command:
FT.AGGREGATE 3801:idx '*' GROUPBY 1 '@pids' REDUCE TOLIST 1 '@username' AS 'users'
These redis commands worked just fine.
NodeJs code I have used to create the index
redisClient.ft.create('3801:idx', {
username: {
type: SchemaFieldTypes.TEXT,
SORTABLE: true,
},
pids: {
type: SchemaFieldTypes.TEXT,
SORTABLE: true,
},
}, {
ON: 'HASH',
PREFIX: '3801:',
})
The generated create redis command from logs:
"FT.CREATE" "3801:idx" "ON" "HASH" "PREFIX" "1" "3801:" "SCHEMA" "username" "TEXT" "SORTABLE" "pids" "TEXT" "SORTABLE"
and for aggregation,
const result = await new Promise((resolve, reject) => {
redisClient.ft.aggregate('3801:idx', '*', {
STEPS: [{
type: AggregateSteps.GROUPBY,
properties: ['@pids'],
REDUCE: [{
type: AggregateGroupByReducers.TOLIST,
property: '@username',
AS: 'users',
}],
}],
}, (err, result) => {
if (err) {
reject(err)
} else {
resolve(result)
}
})
})
console.log('got result:', JSON.stringify(result))
This code generated the following
"FT.AGGREGATE" "3801:idx" "*" "GROUPBY" "1" "@pids" "REDUCE" "TOLIST" "1" "@username" "AS" "users"
Looks like the commands generated are correct. I just confirmed it by copying this to redis-cli and ran. I got the expected result. But the NodeJS code not returning the result
Screenshot from RedisInsight on the data
Can someone please help me on how can I solve this using NodeJs?
I just removed the Promise handler which was surrounded by the aggregate call and it worked just fine
const result = await redisClient.ft.aggregate(indexName, queryPattern, {
STEPS: [{
type: AggregateSteps.FILTER,
expression: `${userList.map(username => `@username=='${username}'`).join(' || ')}`,
}, {
type: AggregateSteps.GROUPBY,
properties: ['@pids'],
REDUCE: [{
type: AggregateGroupByReducers.TOLIST,
property: '@username',
AS: 'users',
}],
}],
})
logger.info('Got result\nSize: ', JSON.stringify(result.total))
logger.debug('\nData: ' + JSON.stringify(result.results))
} catch (error) {
logger.error('Error:', error)
}