0

This is the data [ { "senderID": "64d9c926c17fd183a93d5e35", "receiverID": "64d9c92dc17fd183a93d5e39", "timestamp": "2023-08-14T07:39:45.946Z", "content": "bru", "status": "delivered", "type": "chat", "messageID": "8188946b-67e4-4d86-a927-32842361825c" },........ ]

I just want to select all the status sent and change status to delivered


 if (messageIDs.length === 0) {
        this.chatRepository.jsonSet(
          `rooms:${room?.roomID}`,
          room?.status,
          `$.*[?(@.status=="sent")].status`,
        );
      }


  async jsonSet(key: string, value: any, option?: string) {
    if (!option) {
      option = '$';
    }
    console.log(key, option, value)
    await this.redisProvider.publisher.json.set(key, option, value);
  }

I am failing to pass a string there called 'sent'

Redis Query that failed

JSON.SET rooms:64d9c926c17fd183a93d5e35-64d9c92dc17fd183a93d5e39 $.*[?(@.status=="sent")].status '"delivered"' 

Help is appreciated, I am using npm with redis node version is 20 and redis probably latest version as well

Note: This works both on REDIS CLI and from node Client

JSON.SET rooms:64d9c926c17fd183a93d5e35-64d9c92dc17fd183a93d5e39 $.[*].status '"delivered"'

I have tried

$.*[?(@.status=="sent")]

.*[?(@.status=="sent")]

$.*[?(@.status=="'sent'")]

$.[?(@.status==sent)]

I am failing to pass a string there called 'sent'

EDIT: Have tried to set with the given approaches

''' this.chatRepository.jsonSet( rooms:${rooms?.roomID}, rooms?.status, "$.[?.(@.status=='sent')].status" ); Error: ERR new objects must be created at the root '''

2 Answers2

1

You can use this

JSON.SET rooms:1234 '$.[?(@.status=="sent")].status' '"delivered"'

To change all objects in the top-level array with status sent to be delivered

oshadmi
  • 136
  • 3
  • Yes This is the answer , but i do get error like this "ERR new objects must be created at the root" not sure if its my code or the redis package jsonSet(`rooms:${rooms?.roomID}`,rooms?.status,"$.[?.(@.status=='sent')].status"); – Bruce Armstrong Aug 17 '23 at 06:34
0

Some of these JSONPath things can be tricky. This one is invalid. What it does is start at the root with $. Then the .* selects all the fields on the object in the root. Since there are none, it returns none. Then, assuming those not-found fields are arrays, it matches each object in those array for a status property of sent. Where this matches, it selects those properties.

I like to use jsonpath.com to test out my JSON and corresponding paths. Makes the troubleshooting easier.

Regardless, I got it to work with the following JSONPath:

$[?(@.status=='sent')].status

And here it is working from the CLI:

127.0.0.1:6379> JSON.SET rooms:1234 $ '[ { "senderID": "64d9c926c17fd183a93d5e35", "receiverID": "64d9c92dc17fd183a93d5e39", "timestamp": "2023-08-14T07:39:45.946Z", "content": "bru", "status": "delivered", "type": "chat", "messageID": "8188946b-67e4-4d86-a927-32842361825c" }]'
OK
127.0.0.1:6379> JSON.GET rooms:1234 "$[?(@.status=='delivered')].status"
"[\"delivered\"]"
127.0.0.1:6379> JSON.GET rooms:1234 "$[?(@.status=='sent')].status"
"[]"

I just did a JSON.GET but it should work find for JSON.SET too.

Guy Royse
  • 2,739
  • 12
  • 9
  • Thanks for the link and suggestion but I do get the error saying "ERR new objects must be created at the root" (might be issue with redis) Exact Query this.chatRepository.jsonSet(`rooms:${rooms?.roomID}`, rooms?.status,"$.[?.(@.status=='sent')].status"); – Bruce Armstrong Aug 17 '23 at 06:26
  • This means that the key doesn't exist and the document needs created. You can't insert deeply into a JSON document that doesn't exist. – Guy Royse Aug 17 '23 at 14:39
  • Yes, the client was the issue here, passing room ID along with the string "rooms:" which so it appends rooms:rooms, that's the issue.(passing statically from client when trying out), thanks to u,now i can test commands with cli much better. – Bruce Armstrong Aug 18 '23 at 06:06
  • 1
    Yes it works, thanks a lot, appreciate the help! – Bruce Armstrong Aug 18 '23 at 09:19