I have scenario to insert a new attribute in couchbase document.
For ex : I have a document like:
{
"x" : "value1",
"y" : "value2"
}
I just want to insert another key "z", for which value should be taken from key "y".
My expected result should be like:
{
"x" : "value1",
"y" : "value2",
"z" : "value2"
}
Note : "x" is unique id.
Kindly suggest me couchbase N1QL query for better performance.
If you need to update all documents
UPDATE default SET z = y;
If you need to update based on condition.
UPDATE default SET z = y WHERE x = "value1";
Related
I have a Postgres JSON column (column name = data), in which I wanted to delete all the attributes inside the JSON object.
JSON
{
"headerText": "header_text",
"vendor": {
"id": "some text",
"metadata": 123123,
"startDate": "1234234",
"assetIds": [
"some text"
],
"endDate": "234435",
"publishStart": 12443245,
"publishEnd": 978128123
},
"footerText": "some_text"
}
So, here the attributes inside the vendor json object are dynamic, which means there may be additional attributes.
So I tried the below queries, but was unable to yield the expected result
1. update table_name set data = data::jsonb #- '{vendor.*}'
2. update table_name set data = data::jsonb - '{vendor.*}'::text[]
Expected:
{
"headerText": "header text",
"vendor": {},
"footerText": "some text"
}
Just replace vendor with an empty value by appending it.
update table_name
set data = data || '{"vendor": {}}'
This requires data to be defined as jsonb (which it should be). If it's not, you need to cast it: data::jsonb || ....
If you don't need the vendor key at all, you can also do:
update table_name
set data = data - 'vendor'
which completely removes the key from the value (so it results in {"footerText": "some_text", "headerText": "header_text"})
You can use concatenation to overwrite values in (postgres) json:
update table_name set data = data::jsonb || json_build_object('vendor', json_build_object())::jsonb
PostgreSQL 13
The goal is to rename all src keys in the photos array to image.
I have a table plans which has a column json with a simplified structure similar to the below sample.
{
"id": "some id",
"name": "some name",
"tags": [
{
"keyId": 123,
"valueId": 123
},
{
"keyId": 123,
"valueId": 123
}
],
"score": 123,
"photos": [
{
"src": "someString"
},
{
"src": "someString"
}
],
"payment": true
}
The number of objects in the photos array varies, but in general, it is less than 10, so a non-iterating method would be fine, too.
I tried something like this, but it is only good for modifying the value of a key, not the name of the key itself.
UPDATE
plans
SET
json = jsonb_set(json::jsonb, '{photos, 0, src}', '"image"')
;
With the following attempt, I was actually able to rename the key but it overwrites everything else, so only an object with {"image": "someUrl"} is left:
UPDATE
plans
SET
json = (json -> 'photos' ->> 0)::jsonb - 'src' || jsonb_build_object ('image',
json::jsonb -> 'photos' -> 0 -> 'src')
WHERE json::jsonb ? 'photos' = true;
Is there a way to rename keys as expected?
So in the end I used a variation of my initial jsonb_set method. The solution isn't elegant or efficient, but since it is a one-time operation, it was only important to work:
UPDATE
plans
SET
json = jsonb_set(json::jsonb, '{photos, 0, imageUrl}', (json->'photos'->0->'src')::jsonb)
WHERE
json->'photos'->0->'src' IS NOT NULL
;
This query would add the imageUrl key with the existing value of the src key for the first object (position 0) in the photos array. So it left me with src and imageUrl key.
To remove the src key, I ran the following query
UPDATE
plans
SET
json = json::jsonb #- '{ photos, 0, src}'
;
Repeating this as many times as the maximum number of elements in a photos array eventually solved the issue for me.
I want to update an element in an array object and return only the few elements from the updated array object.
Document:
{
"doctype" : "report",
"name":"nick",
"emailId":"nick123#gmail.com",
"subjects" : [{
"name":"SOA",
"tutor":"roshan",
"classes" : "12",
"mark" : 40,
"subid": "5678"
},
{
"name":"UNIX",
"tutor":"mathew",
"classes" : "9"
"mark" : 50,
"subid" : "3788"
}
],
"id" : "12345"
}
n1q1:
update bucket1
Set i.status = “pass” for i in subjects when i.mark > 40 end
where doctype = "report"
returning *
above query returns the whole document but I want only few element from the updated array object like below. Can you please help me on this . Thanks
Expected query response
{
"id" : "12345",
"subid: “3788”,
"name":"UNIX"
}
Returning clause you can build expression that you want.
You are updating ARRAY, it means it can update more than one element. so you can return as ARRAY, if you want FIRST element replace with ARRAY with FIRST.
UPDATE bucket1 AS b
SET i.status = "pass" FOR i IN b.subjects WHEN i.mark > 40 END
WHERE b.doctype = "report" AND (ANY v IN b.subjects SATISFIES v.mark > 40 END)
RETURNING (ARRAY {v.id, v.subid, v.name} FOR v IN b.subjects WHEN v.mark > 40 END) AS subjects;
You can only return modified info, you will not able to return original info.
I have a set of documents of the type:
contactId: V123132,
{
"accessMap": {
"136400": [
"STANDARD"
],
"136401": [
"STANDARD"
],
"136535": [
"STANDARD"
],
"136672": [
"RG0763",
"ADMIN",
"STANDARD"
],
"136676": [
"RG0763",
"ADMIN",
"STANDARD"
]
}
},
"documentType": "ACS_MAP"
I want to update the keys of the accessMap and append a ":2" at the end of each key in the accessMap,I'm trying to figure out how to write query for that.
What I've done so far is to select the keys of the accessMap I did a:
SELECT OBJECT_NAMES(contact-services.accessMap) from contact-services where documentType = "ACS_MAP"
which gives me:
{
"$1": [
"136400",
"136401",
"136535",
"136672",
"136676"
]
}
I'm not sure if this is the right approach for it..?
To change values you need to use UPDATE statement.
UPDATE statement LHS of SET/UNSET needs path, so you need to aware of the path you want to update.
You have ARRAY you can use any ARRAY functions https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/arrayfun.html or construct new ARRAY
UPDATE default AS d
SET d.accessMap.`136672` = ARRAY_APPENED(d.accessMap.`136672`,"xyz")
WHERE ......;
UPDATE default AS d
SET d.accessMap.[v] = ARRAY_APPEND(d.accessMap.[v], "hello")
FOR v IN OBJECT_NAMES(d.accessMap)
WHEN v IN ["136672", "136676"] END
WHERE ....;
post fix ":2" every key of accessMap. If need specific pattern use CASE expression.
UPDATE default AS d
SET d.accessMap = OBJECT (v.name|| ":2") : v.val FOR v IN OBJECT_PAIRS(d.accessMap) END
WHERE ....;
I have a data field that looks like this :
{ "field1" : [{"name":'name1',"value1":true},
{"name":'name2',"value2":false}
],
"field2" : [{"name":'name1',"value1":true},
{"name":'name2',"value2":false}
]
}
Is it possible to update a specific field with an update ?
create table t_json (
t_data json
);
insert into t_json values('{"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}],"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}]}');
select t_data->'field1'
from t_json;
I tried this :
update t_json
set t_data->'a' = '[{"value1" : true, "value2" : false}]';
But I get an error : "syntax error at or near ->
What is missing ?
I wanted to post this here in case it helps anybody else. By all means use JSON over JSONB unless you actually need features that JSONB affords you. In general, if you need to perform queries on the JSON data itself, use JSONB. If you are just needing to store data, use JSON.
Anyhow, here is how I am updating a JSON[] field:
UPDATE foo SET bar = ARRAY[$${"hello": "world"}$$, $${"baz": "bing"}$$]::JSON[]
The important things to notice are this:
The array is wrapped like this: ARRAY[ ... ]::JSON[]
Each item in the array is wrapped like this: $${ "foo": "bar" }$$
It is worth noting that this same technique can be used for other array types. For example, if you have a text[] column, the query would look like this:
UPDATE foo SET bar = ARRAY[$$hello world$$, $$baz bing$$]::TEXT[]`
Fixing your typos
Doubt it. This is not valid json. name1 and name2 must be double quoted. To ease working with json, ALWAYS use double quotes. ALWAYS query-quote with double-dollar.
{ "field1" : [{"name":'name1',"value1":true},
{"name":'name2',"value2":false}
],
"field2" : [{"name":'name1',"value1":true},
{"name":'name2',"value2":false}
]
}
And, what you INSERTED is also funky.. ALWAYS paste beautified valid JSON in your question.
{
"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}],
"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}]
}
Let's change that and fix it.
{
"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}],
"field2":[{"name":"name1","value" : true},{"name":"name2","value" : false}]
}
Now let's put it in a query..
TRUNCATE t_json;
INSERT INTO t_json (t_data) VALUES ($$
{
"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}],
"field2":[{"name":"name1","value" : true},{"name":"name2","value" : false}]
}
$$);
Making the update of the JSON
Now it works.. Now you can update it as you want..
UPDATE t_json
SET t_data = jsonb_set(
t_data::jsonb,
'{field1}',
$${"whatever":1}$$
);
Change from JSON to JSONB
Notice we're having to cast to jsonb. As a general rule, NEVER use JSON (not everyone agrees, see comments). There is no point. Instead use the newer JSONB.
ALTER TABLE t_json ALTER COLUMN t_data TYPE jsonb ;
Now you can do
UPDATE t_json
SET t_data = jsonb_set(
t_data,
'{field1}',
$${"whatever":1}$$
);