sequelize: Error when using `$contains` operator with JSONB array field
Hello, I have a table with a field doc
which is of type JSONB. Each doc
has a browsers
array. I try to search for rows where doc->browsers contains some value using the $contains
operator, like this:
model.find({where: {
doc.browsers = {
$contains: [browserName]
}
}})
And got this error:
ERROR: operator does not exist: text @> text[] at character 478
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Do you know how to support this use case in Sequelize? Thanks!
About this issue
- Original URL
- State: open
- Created 8 years ago
- Reactions: 16
- Comments: 44 (14 by maintainers)
really need this bug fixed…
In PostgreSQL, Can be used
$contains
operator with JSONB ARRAY by…Data Format
In Sequelize
query
update 2022.04.07
if you want to use an index, you shouldn’t use the code above. In my case, I just use literal.
Data Format
In Sequelize
Given json structure
I can get rows having
name = "chrome"
inbrowsers
array using below queryHere is the generated SQL statement
Encountered this issue myself today in MySQL with a JSON array. My current workaround is:
This will find Users with permissions field that contain the value “SOME_PERMISSION”. For example user with: [“SOME_PERMISSION”, “OTHER_PERMISSION”], will be found.
This is only a workaround, I would prefer a solution to get $contains to work directly with MySQL JSON data fields.
Keep it open
please add good documentation with good examples for jsonb fields, it’s not clear, and the only way is to hack source
@samuelgoldenbaum
I’m just suggesting one way. If you consider performance, don’t put JSONB ARRAY on where clause.
This appears to be an issue for JSONB in MySQL as well, so +1
my current workaround:
Could you open another issue for that? It’s a valid issue, and the related regexp needs to be improved, but let’s keep this issue strictly about automatically casting to JSONB for this scenario
Edit: the other issue is #14410
@vkm912 There is no JSONB field in MySQL, only JSON DataType is supported in MySQL/Sequelize. Therefore his solution will not work with the MySQL dialect setup in Sequelize.
You could find a workaround for almost anything using ‘literal’ and ‘fn’ following the JSON MySQL documentation.
But it would be nice to see it being supported natively in Sequelize.
as @contra mentioned, the most correct query looks like:
This is the way how I managed to make it using the sequelize query builder:
For me it’s also very interesting how can you receive the nested field not as a text but as
jsonb
. So the default approachOp.includes
should work.What is also complex - to stringify
javascript
array to the postgresql array. I haven’t found any suitable sequelize method.Also experienced that issue: { $not: { $contains: [ 1, 2, 3 ] } } is broken
Also noticed that
{ $not: { $contains: [ 1, 2, 3 ] } }
is broken even with this bug fixed internally.@dhylbert
Seems to work correct for me - However, it only does exact matches, not substrings (so
'$contains': { components: [ 'a' ]}
does not work)