Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aerospike - add new key/value pair in nested object

In Aerospike, how can I add a new key/value pair in nested object stored in bins of type map?

For ex, I have a bins of type map against which I need to store below key/value pairs.

{
  "a" : "apple",
  "b" : "ball",
  "c" : { "d" : "dog", "e" : "elephant" }, 
  "f" : { "g" : { "h" : "horse" } },
  "i" : { "j" : "jackal", "k" : { "l" : "lion", "m" : "monkey" } }
}  

Now, I want to update an existing nested object against key "k" to add one more key value pair like below.

"k" : { "l" : "lion", "m" : "monkey", "n" : "nest" }

Final result should be like below.

{
  "a" : "apple",
  "b" : "ball",
  "c" : { "d" : "dog", "e" : "elephant" }, 
  "f" : { "g" : { "h" : "horse" } },
  "i" : { "j" : "jackal", "k" : { "l" : "lion", "m" : "monkey", "n" : "nest" } }
}  

Any suggestions on how to achieve this? It's a NodeJS (10.6.0) application & I'm using NodeJS aerospike client (3.6.1) to interact with Aerospike (4.3.0.7).

like image 439
Ayaz Pasha Avatar asked Dec 17 '22 20:12

Ayaz Pasha


1 Answers

Updates on nested CDT maps and lists are possible now, using Aerospike server version 4.6 or later and Aerospike Node.js client version 3.12 or later. That update introduced the withContext() function on list and map operations that lets you specify the context in which the list/map operation is to be executed. You can find more information in the documentation for the new CdtContext class.

Here is how you would perform the update given in your example:

const Aerospike = require('aerospike')
const maps = Aerospike.maps

Aerospike.connect().then(async (client) => {
  const key = new Aerospike.Key('test', 'test', 'test')

  const map = {
    "a" : "apple",
    "b" : "ball",
    "c" : { "d" : "dog", "e" : "elephant" },
    "f" : { "g" : { "h" : "horse" } },
    "i" : { "j" : "jackal", "k" : { "l" : "lion", "m" : "monkey" } }
  }
  console.log('BEFORE:', map)
  await client.put(key, map)

  await client.operate(key, [
    maps.put('i', 'n', 'nest')
        .withContext((ctx) => ctx.addMapKey('k'))
  ])
  const record = await client.get(key)
  console.log('AFTER:', record.bins)

  client.close()
}).catch((error) => {
  console.error(error)
  if (error.client) error.client.close()
})

Here is what you would get, when you run the example:

$ node nested-map-update-example.js
BEFORE: {
  a: 'apple',
  b: 'ball',
  c: { d: 'dog', e: 'elephant' },
  f: { g: { h: 'horse' } },
  i: { j: 'jackal', k: { l: 'lion', m: 'monkey' } }
}
AFTER: {
  a: 'apple',
  b: 'ball',
  c: { d: 'dog', e: 'elephant' },
  f: { g: { h: 'horse' } },
  i: { j: 'jackal', k: { l: 'lion', m: 'monkey', n: 'nest' } }
}
like image 57
Jan Hecking Avatar answered Jan 05 '23 04:01

Jan Hecking