English
Added in HBuilderX 3.5.2, need to activate redis
uniCloud provides two kinds of databases: MongoDB and Redis. And provides a linkage mechanism, which can easily cache the data in MongoDB into Redis.
Applicable scene:
Data that needs to be accessed frequently, but not frequently modified. For example, public data such as infrequently updated homepage lists, banners, hot searches, and top rankings.
The frequency of these query requests is high. If you go to MongoDB to read each time, it is slow and expensive, and it may timeout or exceed concurrency.
Using JQL Cache Redis
, you can easily cache these query results in Redis. It not only improves the access speed, but also improves the concurrent performance, and also reduces the running time of cloud functions and the number of database reads.
JQL Cache Redis
can be used regardless of clientDB components or API, or cloud function/cloud object JQLJQL Cache Redis
in cloud functions/cloud objects, you need to load Redis and JQL extension libraries and rely on the uni-config-center
public moduleuni-config-center
在uniCloud/cloudfunctions/common/uni-config-center
下创建uni-jql-cache-redis.json
文件(注意此文件是标准json格式,不支持注释)
If uni-config-center
is not installed, please import it in the plugin market, the plugin address: uni-config-center
The uni-jql-cache-redis.json
file is an array where each item is a cache configuration. The example content is as follows
[{
"id": "test-get", // 缓存id,不可重复,必填
"jql": "db.collection('test').limit(10).get()", // 要缓存的数据库指令,必填
"expiresIn": 3600 // 缓存有效期,单位秒,非必填
}]
expiresIn
is the cache validity period, in seconds. The start time of the validity period is the time from the first cache to redis (in fact, the validity period that comes with redis). If not filled, it means that it will not expire according to time.
After the configuration is successful, when the client or cloud JQL queries db.collection('test').limit(10).get()
, it will first go to redis to find it. If it is not found, it will find it from MongoDB and then automatically cache into redis.
When the cache is hit, clientDB or cloud functions/cloud objects using the jql extension will output the following logs
"当前请求需使用Redis缓存"
"返回Redis内缓存的结果"
When the cache is missed, clientDB or cloud functions/cloud objects using the jql extension will output the following logs
"当前请求需使用Redis缓存"
"未命中Redis缓存,设置Redis缓存"
JQL Cache Redis
will cache the query results corresponding to the cache configuration in the redis cache whose key is unicloud:jql-cache:${id}:string
. It can be found in the redis view of the uniCloud web console.
When configuring "jql": "db.collection('test').limit(10).get()"
, please note that the quotation marks need to be escaped when placing ordinary JQL statements in the value of json, see below.
Since the query statement needs to be placed in the json file, and the strings in the json need to be surrounded by quotation marks, the scenarios that use double quotation marks in the query statement need to be escaped and then placed in the configuration.
E.g:
// jql
db.collection('book').where('author=="caoxueqin"').get()
// after escaping
"db.collection('book').where('author==\"caoxueqin\"').get()"
If your query statement is more complex, it is more troublesome to add escape characters one by one. The escaped string can be obtained as follows
'use strict';
const fs = require('fs')
const path = require('path')
exports.main = async (event, context) => {
console.log(
fs.readFileSync(
path.resolve(__dirname, 'test.jql')
).toString()
)
};
test.jql
file in the cloud function root directory, the content is the jql query statement to be escapeddb.collection('book').where('author=="caoxueqin"').get()
21:56:44.135 [本地运行]"db.collection('book').where('author==\"caoxueqin\"').get()" uniCloud-aliyun/cloudfunctions/test/index.js:5:10
db.getCloudEnv()
or $cloudEnv_
.where('name=="caoxueqin"')
, the escaped single quote is used when calling, .where('name==\'caoxueqin\'')
, then this call query will not go to the redis cache. Subsequent optimization of this problem##multiSend uses cache @multi-send
When using multiSend to send multiple instructions at the same time, caching the entire multiSend is not supported. Each instruction needs to be cached separately.
example:
const book = db.collection('book').limit(10).getTemp()
const author = db.collection('author').limit(10).getTemp()
db.multiSend(book,author)
For the above database directives, you cannot directly configure jql in the cache configuration as const book = db.collection('book').limit(10).getTemp();const author = db.collection('author').limit( 10).getTemp();db.multiSend(book,author)
You need to configure the query statement of the book table and the query statement of the author table separately. Note that the getTemp method also needs to be changed to the get method.
[{
"id": "book-get",
"jql": "db.collection('book').limit(10).get()",
"expiresIn": 3600
}, {
"id": "author-get",
"jql": "db.collection('author').limit(10).get()",
"expiresIn": 3600
}]
The cache statement configured when joining the table is also consistent with the jql syntax
example:
const book = db.collection('book').limit(10).getTemp()
const author = db.collection('author').getTemp()
db.collection(book, author).get()
uni-jql-cache-redis.json
cache configuration is as follows
[{
"id": "book-author-lookup",
"jql": "const book = db.collection('book').limit(10).getTemp();const author = db.collection('author').getTemp();db.collection(book, author).get()",
"expiresIn": 3600
}]
When the data in MongoDB changes, the cache in Redis should be actively deleted.
For example, after caching the data of the banner carousel in Redis, and modifying the banner in the admin, you should operate redis in the cloud function at the same time, and set the banner cache to invalid
Use the redis delete command to pass in the key corresponding to the cache to delete the cache.
example:
const redis = uniCloud.redis()
const id = 'banner' // 这个id就是`uni-jql-cache-redis.json`中配置的id
const cacheKey = `unicloud:jql-cache:${id}:string`
await redis.del(cacheKey)