-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DOC-4345 added testable JSON index/query example #2864
base: emb-examples
Are you sure you want to change the base?
Changes from 3 commits
8824115
127dc2a
3a56084
8b804e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
// EXAMPLE: js_home_json | ||
// REMOVE_START | ||
import assert from 'assert'; | ||
// REMOVE_END | ||
// STEP_START import | ||
import { | ||
createClient, | ||
SchemaFieldTypes, | ||
AggregateGroupByReducers, | ||
AggregateSteps, | ||
} from 'redis'; | ||
// STEP_END | ||
|
||
// STEP_START connect | ||
const client = await createClient(); | ||
await client.connect(); | ||
// STEP_END | ||
// REMOVE_START | ||
try { | ||
await client.ft.dropIndex('idx:users', { DD: true }); | ||
} catch{} | ||
|
||
await client.del('user:1', 'user:2', 'user:3'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Often, there isn't an existing index (hence the try...catch as I mentioned in the previous reply), so presumably the keys don't get deleted in this case. However, keys like user:1, etc, are common in docs and test code. If user:1 exists but isn't a JSON key then you'll get the "wrong kind of value" error. If you think I'm being overly cautious here then I'll remove the client.del here, but I have seen this kind of thing happen occasionally. |
||
// REMOVE_END | ||
|
||
// STEP_START create_data | ||
var user1 = { | ||
name: "Paul John", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Found/replaced these throughout the file now. |
||
email: "[email protected]", | ||
age: 42, | ||
city: "London" | ||
} | ||
|
||
var user2 = { | ||
name: "Eden Zamir", | ||
email: "[email protected]", | ||
age: 29, | ||
city: "Tel Aviv" | ||
} | ||
|
||
var user3 = { | ||
name: "Paul Zamir", | ||
email: "[email protected]", | ||
age: 35, | ||
city: "Tel Aviv" | ||
} | ||
// STEP_END | ||
|
||
// STEP_START make_index | ||
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:' | ||
}); | ||
// STEP_END | ||
|
||
// STEP_START add_data | ||
var user1Added = await client.json.set('user:1', '$', user1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there is no reason to make 3 round trips for 3 SET, you can do: 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)
]); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good tip, thanks. |
||
var user2Added = await client.json.set('user:2', '$', user2); | ||
var user3Added = await client.json.set('user:3', '$', user3); | ||
// STEP_END | ||
// REMOVE_START | ||
assert.equal('OK', user1Added); | ||
assert.equal('OK', user2Added); | ||
assert.equal('OK', user3Added); | ||
// REMOVE_END | ||
|
||
// STEP_START query1 | ||
var 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}`); | ||
}); | ||
// >>> ID: user:3, name: Paul Zamir, age: 35 | ||
// STEP_END | ||
// REMOVE_START | ||
assert.strictEqual(1, findPaulResult.total); | ||
|
||
var paulDoc = findPaulResult.documents[0]; | ||
|
||
assert.equal('user:3', paulDoc.id); | ||
// REMOVE_END | ||
|
||
// STEP_START query2 | ||
var citiesResult = await client.ft.search('idx:users', '*',{ | ||
RETURN: "city" | ||
}); | ||
|
||
console.log(citiesResult.total); // >>> 3 | ||
|
||
citiesResult.documents.forEach(cityDoc => { | ||
console.log(cityDoc.value); | ||
}); | ||
// >>> {city: 'London'} | ||
// >>> {city: 'Tel Aviv'} | ||
// >>> {city: 'Tel Aviv'} | ||
// STEP_END | ||
// REMOVE_START | ||
assert.strictEqual(3, citiesResult.total); | ||
|
||
citiesResult.documents.sort((a, b)=> a.id < b.id); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are we sorting on the client side and not using RediSearch it self?! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just for the test code. For other client examples I've written, the order of the documents returned is not deterministic, so you need to sort before using the asserts, otherwise you get an occasionally flaky test. The reason I don't add the sort option to the command is simply that the other client examples don't use the sort option here - just keeping them all consistent. |
||
assert.equal('user:1', citiesResult.documents[0].id); | ||
assert.equal('user:2', citiesResult.documents[1].id); | ||
assert.equal('user:3', citiesResult.documents[2].id); | ||
// REMOVE_END | ||
|
||
// STEP_START query3 | ||
var 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}`); | ||
}); | ||
// >>> London - 1 | ||
// >>> Tel Aviv - 2 | ||
// STEP_END | ||
// REMOVE_START | ||
assert.strictEqual(2, aggResult.total); | ||
|
||
aggResult.results.sort((a, b) => a.city < b.city); | ||
assert.equal('London - 1', `${aggResult.results[0].city} - ${aggResult.results[0].count}`); | ||
assert.equal('Tel Aviv - 2', `${aggResult.results[1].city} - ${aggResult.results[1].count}`) | ||
// REMOVE_END | ||
|
||
await client.quit(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for this is that dropIndex generally throws an error if you try to drop an index that doesn't exist (at least in the clients for other languages). It seemed to work OK without the try...catch locally, but I got an error from the CI when I made the PR. I assumed the try...catch was required and it fixed the error. If I'm doing this the wrong way or misinterpreting the build error then please let me know.