how to update JSONB column using knexjs, bookshelfjs - postgresql

I have a JSONB column in PostgreSQL database like {lat: value, lon: value}. I want to change any specific value at a time eg. lat, but I am not sure how I can achieve this using bookshelf.js or knex.js. I tried using jsonb_set() method specified in Postgres documentation but I am not sure if I used that correctly. Can somebody please suggest me how can I do this? or what is the correct syntax to do this? Thanks.

AFAIK only knex based thing that supports writing to and extracting data from postgresql jsonb columns is objection.js ORM.
With plain knex you need to use raw to write references:
knex('table').update({
jsonbColumn: knex.raw(`jsonb_set(??, '{lat}', ?)`, ['jsonbColumn', newLatValue])
})
You can check generated SQL here https://runkit.com/embed/44ifdhzxejf1
Originally answered in: https://github.com/tgriesser/knex/issues/2264
More examples how to use jsonb_set with knex can be found in following answers
How to update a jsonb column's field in PostgreSQL?
What is the best way to use PostgreSQL JSON types with NodeJS

Jsonb field update using knex.js
return knex("tablename").update({
jsonbkey: knex.raw(`
jsonb_set(jsonbkey, '{city}','"Ayodhya"')
`)
}).where({"id" :2020})
The jsonbkey will be the column name, where the datatype is jsonb.
The tablename is the name of your table.
The city is the object key.
If there is multiple level of object then you can use dot. Like '{city.id}'

let result = await db().raw(`UPDATE widget
SET name = ?,
jsonCol= jsonCol::jsonb || ?::jsonb
WHERE id = ?`,
[name, JSON.stringify(newJsonData), id);
this knex query helps to update any json column by overriding specific keys in the value supplied to the right hand side of || operator. DO NOT forget to typecast the values with ::jsonb

Related

fuzzy finding through database - prisma

I am trying to build a storage manager where users can store their lab samples/data. Unfortunately, this means that the tables will end up being quite dynamic, as each sample might have different data associated with it. I will still require users to define a schema, so I can display the data properly, however, I think this schema will have to be represented as a JSON field in the underlying database.
I was wondering, in Prisma, is there a way to fuzzy search through collections. Could I type something like help and then return all rows that match this expression ANYWHERE in their columns? (including the JSON fields). Could i do something like this at all with posgresql? Or with MongoDB?
thank you
You can easily do that with jsonb in PostgreSQL.
If you have a table defined like
CREATE TABLE userdata (
id bigint PRIMARY KEY,
important_col1 text,
important_col2 integer,
other_cols jsonb
);
You can create an index like this
CREATE INDEX ON userdata USING gin (other_cols);
and search efficiently with
SELECT id FROM userdata WHERE other_cols #> '{"attribute": "value"}';
Here, #> is the JSON containment operator in PostgreSQL.
Yes, in PostgreSQL you surely can do this. It's quite straightforward. Here is an example.
Let your table be called the_table aliased as tht. Cast an entire table row as text tht::text and use case insensitive regular expression match operator ~* to find rows that contain help in this text. You can use more elaborate and powerful regular expression for searching too.
Please note that since the ~* operator will defeat any index, this query will result in a sequential scan.
select * -- or whatever list of expressions you need
from the_table as tht
where tht::text ~* 'help';

How to modify field with jsonPath in PostgreSQL?

How to modify a field using jsonPath in PostgreSQL like SQL Server JSON_MODIFY (https://learn.microsoft.com/en-us/sql/t-sql/functions/json-modify-transact-sql?view=sql-server-ver15)?
Thanks!
There are currently no ways to update JSON properties using JsonPath. The only way is with jsonb query jsonb_set

How to map a column to JSONB instead of JSON, with Doctrine and Postgresql?

In my project I'm using Doctrine doctrine 2.5.4/postgres 9.5. I'm trying to add a jsonb field using YAML:
fields:
obj: json_array
This gets interpreted as a json column type (and not jsonb). The specification notes about picking up json or jsonb:
Chosen if the column definition contains the jsonb option inside the platformOptions attribute array and is set to true.
But platformOptions doesn't seem to work (tried to add it below obj, at the top... with no success). How can I add a jsonb field?
This is supported by doctrine/dbal v2.6+ (it requires PHP 7.1). All you need to do is use json_array and set options={"jsonb"=true} I tested this on doctrine/dbal v2.6.3
This is what it looks like in PHP format:
/**
* #ORM\Column(type="json_array",nullable=true,options={"jsonb"=true})
*/
private $details;
and it creates a query such as (for an existing table):
ALTER TABLE mytable ADD details JSONB NOT NULL;
More details about type mapping can be found at Doctrine mapping matrix.
Use boldtrn/jsonb-bundle, it provides a jsonb doctrine type as well as custom functions to access the special operators provided by the PostgreSQL jsonb data type.

Converting lat-long to PostGIS geometry without querying the database

I have a table in postgresql with a PostGIS geometry(point, 4326) column (location, using SRID 4326) and I have a Python application that using SQL Alchemy updates the table (the rest of the columns) without any problem.
Now, I need to update the location column and I know I can use the proper text representation of a given location to update the column using SQL Alchemy without the need to use GEOAlchemy, for instance I can update the column with the value: '0101000020E6100000AEAC7EB61F835DC0241CC418A2F74040'
which corresponds to lat:33.9346343 long:-118.0488106
The question is: is there a way to compute in Python this '0101000020E6100000AEAC7EB61F835DC0241CC418A2F74040' having this (33.9346343 ,-118.0488106) as an input without querying the database? or any way to update the column using a proper text input?
I know I can use SQLAlchemy to execute this query:
select st_setsrid(st_makepoint(-118.0488106, 33.9346343),4326)
and obtain the value to update the column, but I want to avoid that.
Thanks in advance!
The solution to this problem is rather easier than it seems. To update the field using text and the input lat-long all I needed to do was defining the SRID in the text assign:
location = 'SRID=4326;POINT(-118.0488106 33.9346343)'
This will update the geometry(point,4326) column properly and when you do a select in the table the value of the column is the expected one:
"0101000020E6100000AEAC7EB61F835DC0241CC418A2F74040"
Thanks guys!

DB2 index based on substring of field values

Is it possible to create an index of a table based on substring of one or more field values in DB2 ?
The docs imply that you can create an index on a "key-expression" rather than just a vanilla column see key-expression here.