Можно ли искать в Aerospike все ключи, начинающиеся с определенного префикса?

Поэтому я хочу смоделировать наши существующие данные Redis в aerospike. Одно требование, которое у нас есть, — иметь возможность получить все ключи для данного пользователя. Например, скажем, у нас есть такие ключи, как <id>:<timestamp>. Теперь, в какой-то момент времени, мне нужно получить все ключи для заданного id, где мне потребуется что-то вроде поиска префикса по всем ключам в пространстве имен aerospike (которые индексируются), чтобы получить значения для всех ключей <id>:<timestamp>. Хотелось бы узнать, возможно ли это, и если да, то как.


person gravetii    schedule 13.05.2016    source источник


Ответы (1)


Вы не можете сделать запрос по ключевому префиксу напрямую. Сервер хранит только дайджест ключа, поэтому значение ключа (<id>:<timestamp> в вашем случае) не индексируется.

Способ смоделировать это — добавить часть <id> вашего ключа в качестве отдельной корзины записей. Затем вы можете проиндексировать эту корзину и выполнить для нее запрос.

Вот простой пример — он использует клиент Aerospike Node.js, но концепция одна и та же, независимо от того, какой клиент вы предпочитаете:

const Aerospike = require('aerospike')

const ns = 'test'
const set = 'demo'

// connect to cluster and create index on 'id' bin
var client = Aerospike.client()
client.connect((err) => {
  assertOk(err, 'connecting to cluster')
  createIndex('id', 'id_idx', Aerospike.indexDataType.STRING, () => {

    // create a new sample record
    var userId = 'user1'
    var ts = new Date().getTime()
    var key = new Aerospike.Key(ns, set, `${userId}:${ts}`)
    var record = { id: userId, value: Math.random() }
    client.put(key, record, (err) => {
      assertOk(err, 'write record')

      // query for records with matching 'id'
      var query = client.query(ns, set)
      query.where(Aerospike.filter.equal('id', userId))
      var stream = query.foreach()
      stream.on('error', (error) => assertOk(error, 'executing query'))
      stream.on('end', () => client.close())
      stream.on('data', (record, meta, key) => {
        console.log(record)
      })
    })
  })
})

function assertOk (err, message) {
  if (err) {
    console.error('ERROR: %s - %s', message, err)
    process.quit()
  }
}

function createIndex (bin, name, datatype, callback) {
  var index = {
    ns: ns,
    set: set,
    bin: bin,
    index: name,
    datatype: datatype
  }
  client.createIndex(index, (err, job) => {
    assertOk(err, 'creating index')
    job.waitUntilDone(100, (err) => {
      assertOk(err, 'creating index')
      callback()
    })
  })
}

Надеюсь это поможет!

person Jan Hecking    schedule 13.05.2016
comment
Можем ли мы следовать этому, если id не уникален? Или нам придется пропустить часть индексации? В таком случае мне следует переосмыслить дизайн, поскольку без индексации поиск может быть медленным, верно? - person paradocslover; 02.08.2021