[英]node-redis/search query elements by geospatial position and additional indexes
我希望能夠基於 3 個不同的索引查詢 redis 緩存中的元素。 這些索引將是:
String
的 MAC 地址。number
。latitude
和longitude
(能夠進行空間查詢)。我已經看到 Redis 支持使用 redis 搜索和本地地理空間 api 進行多重索引。
所以使用 nodejs 和 node-redis 我寫了以下索引:
client.ft.create(
'idx:cits',
{
mid: {
type: SchemaFieldTypes.TEXT
},
timestamp: {
type: SchemaFieldTypes.NUMERIC,
sortable: true
},
position: {
type: SchemaFieldTypes.GEO
}
},
{
ON: 'HASH',
PREFIX: 'CITS'
}
)
現在,我想在數據庫中插入包含這 3 個參數的記錄以及一個存儲一些有效負載的附加String
。 我試過使用
await client.hSet('CITS:19123123:0:0:00:00:5e:00:53:af', {
timestamp: 19123123,
position: {latitude:0, longitude:0},
mid: '00:00:5e:00:53:af',
message: 'payload'
})
但我收到以下錯誤:
throw new TypeError('Invalid argument type');
^
TypeError: Invalid argument type
所以,我不能那樣添加緯度和經度,我也嘗試使用模塊ngeohash
並計算一個11 個字符寬的 geohash ,如下所示:
await client.hSet('CITS:19123123:0:0:00:00:5e:00:53:af', {
timestamp: 19123123,
position: geohash.encode(0, 0, 11),
mid: '00:00:5e:00:53:af',
message: 'payload'
})
它沒有給出任何錯誤,但是當使用redis 搜索查詢時,它沒有找到它附近的點。
我什至有可能做我想做的事嗎? 如果是這樣,您將如何將數據輸入到 redis 數據庫中?
這是一個最小的可重現示例(我使用"ngeohash": "^0.6.3"
和"redis": "^4.5.0"
):
const { createClient, SchemaFieldTypes } = require('redis')
const geohash = require('ngeohash')
const client = createClient()
async function start(client) {
await client.connect()
try {
// We only want to sort by these 3 values
await client.ft.create(
'idx:cits',
{
mid: {
type: SchemaFieldTypes.TEXT
},
timestamp: {
type: SchemaFieldTypes.NUMERIC,
sortable: true
},
position: {
type: SchemaFieldTypes.GEO
}
},
{
ON: 'HASH',
PREFIX: 'CITS'
}
)
} catch (e) {
if (e.message === 'Index already exists') {
console.log('Skipping index creation as it already exists.')
} else {
console.error(e)
process.exit(1)
}
}
await client.hSet('CITS:19123123:0:0:00:00:5e:00:53:af', {
timestamp: 19123123,
position: geohash.encode(0, 0, 11),
mid: '00:00:5e:00:53:af',
message: 'payload'
})
await client.hSet('CITS:19123123:0.001:0.001:ff:ff:ff:ff:ff:ff', {
timestamp: 19123123,
position: geohash.encode(0.001, 0.001, 11),
mid: 'ff:ff:ff:ff:ff:ff',
message: 'payload'
})
const results = await client.ft.search(
'idx:cits',
'@position:[0 0 10000 km]'
)
console.log(results)
await client.quit()
}
start(client)
另外,我想問一下是否有另一種類型的數據庫更適合我的需要。 我選擇了 redis,因為它提供低延遲,這是我環境中的最大限制(我可能每秒執行的寫入次數多於讀取次數)。 我只希望它充當中間緩存,因為持久數據將存儲在另一個不需要很快的數據庫中。
謝謝你。
您收到Invalid argument type
錯誤,因為 Redis 不支持散列中的嵌套字段。
“GEO 允許針對此屬性中的值進行地理范圍查詢。屬性的值必須是包含經度(第一個)和以逗號分隔的緯度的字符串”( https://redis.io/commands/ft.create/ )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.