簡體   English   中英

node-redis/通過地理空間 position 和附加索引搜索查詢元素

[英]node-redis/search query elements by geospatial position and additional indexes

我希望能夠基於 3 個不同的索引查詢 redis 緩存中的元素。 這些索引將是:

  1. 存儲為String的 MAC 地址。
  2. 一個number
  3. latitudelongitude (能夠進行空間查詢)。

我已經看到 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM