This means that
path
option syntax differs between database connectors - for example, the following is a valid MySQL
path
value:
$petFeatures.petName
The following is a valid PostgreSQL
path
value:
["petFeatures", "petName"]
Filter on exact field value
The following query returns all users where the value of
extendedPetsData
matches the
json
variable exactly:
var json ={[{ name:'Bob the dog'},{ name:'Claudine the cat'}]}
const getUsers =await prisma.user.findMany({
where:{
extendedPetsData:{
equals: json,
},
},
})
The following query returns all users where the value of
extendedPetsData
does
not
match the
json
variable exactly:
var json ={
extendedPetsData:[{ name:'Bob the dog'},{ name:'Claudine the cat'}],
}
const getUsers =await prisma.user.findMany({
where:{
extendedPetsData:{
not: json,
},
},
})
Filter on object property
In
and later, you can filter on a specific property inside a block of JSON. In the following examples, the value of
extendedPetsData
is a one-dimensional, unnested JSON object:
{
"petName":"Claudine",
"petType":"House cat"
}
The following query returns all users where the value of
petName
is
"Claudine"
:
PostgreSQL
MySQL
const getUsers =await prisma.user.findMany({
where:{
extendedPetsData:{
path:['petName'],
equals:'Claudine',
},
},
})
The following query returns all users where the value of
petType
contains
"cat"
:
You can filter on nested JSON properties. In the following examples, the value of
extendedPetsData
is a JSON object with several levels of nesting.
{
"pet1":{
"petName":"Claudine",
"petType":"House cat"
},
"pet2":{
"petName":"Sunny",
"petType":"Gerbil",
"features":{
"eyeColor":"Brown",
"furColor":"White and black"
}
}
}
The following query returns all users where
"pet2"
→
"petName"
is
"Sunny"
:
PostgreSQL
MySQL
const getUsers =await prisma.user.findMany({
where:{
extendedPetsData:{
path:['pet2','petName'],
equals:'Sunny',
},
},
})
The following query returns all users where:
"pet2"
→
"petName"
is
"Sunny"
"pet2"
→
"features"
→
"furColor"
contains
"black"
PostgreSQL
MySQL
const getUsers =await prisma.user.findMany({
where:{
AND:[
{
extendedPetsData:{
path:['pet2','petName'],
equals:'Sunny',
},
},
{
extendedPetsData:{
path:['pet2','features','furColor'],
string_contains:'black',
},
},
],
},
})
Filtering on an array value
You can filter on the presence of a specific value in a scalar array (strings, integers). In the following example, the value of
extendedPetsData
is an array of strings:
["Claudine","Sunny"]
The following query returns all users with a pet named
"Claudine"
:
PostgreSQL
MySQL
const getUsers =await prisma.user.findMany({
where:{
extendedPetsData:{
array_contains:['Claudine'],
},
},
})
Note
: In PostgreSQL, the value of
array_contains
must be an array and not a string, even if the array only contains a single value.
You can filter on the presence of a specific value in a scalar array (strings, integers). In the following examples, the value of
extendedPetsData
includes nested scalar arrays of names:
The following query returns all users that foster a cat named
"Fido"
:
PostgreSQL
MySQL
const getUsers =await prisma.user.findMany({
where:{
extendedPetsData:{
path:['cats','fostering'],
array_contains:['Fido'],
},
},
})
Note
: In PostgreSQL, the value of
array_contains
must be an array and not a string, even if the array only contains a single value.
The following query returns all users that foster cats named
"Fido"
and
"Bob"
:
PostgreSQL
MySQL
const getUsers =await prisma.user.findMany({
where:{
extendedPetsData:{
path:['cats','fostering'],
array_contains:['Fido','Bob'],
},
},
})
JSON object arrays
PostgreSQL
MySQL
const json =[{ status:'expired', insuranceID:92}]
const checkJson =await prisma.user.findMany({
where:{
extendedPetsData:{
path:['insurances'],
array_contains: json,
},
},
})
If you are using PostgreSQL, you must pass in an array of objects to match, even if that array only contains one object:
[{ status:'expired', insuranceID:92}]
// PostgreSQL
If you are using MySQL, you must pass in a single object to match:
{ status:'expired', insuranceID:92}
// MySQL
If your filter array contains multiple objects, PostgreSQL will only return results if
all
objects are present - not if at least one object is present.
You must set
array_contains
to a JSON object, not a string. If you use a string, Prisma Client escapes the quotation marks and the query will not return results. For example:
console.log(userQueries.length+' queries to run!')
await prisma.$transaction(userQueries)
}
const json =[{ status:'expired', insuranceID:92}]
const checkJson =await prisma.user.findMany({
where:{
extendedPetsData:{
path:['insurances'],
array_contains: json,
},
},
})
console.log(checkJson.length)
Using
null
Values
There are two types of
null
values possible for a
JSON
field in an SQL database.
Database
NULL
: The value in the database is a
NULL
.
JSON
null
: The value in the database contains a JSON value that is
null
.
To differentiate between these possibilities, we've introduced three
null enums
you can use:
JsonNull
: Represents the
null
value in JSON.
DbNull
: Represents the
NULL
value in the database.
AnyNull
: Represents both
null
JSON values and
NULL
database values. (Only when filtering)
From v4.0.0,
JsonNull
,
DbNull
, and
AnyNull
are objects. Before v4.0.0, they were strings.
When filtering using any of the
null enums
you can not use a shorthand and leave the
equals
operator off.
These
null enums
do not apply to MongoDB because there the difference between a JSON
null
and a database
NULL
does not exist.
The
null enums
do not apply to the
array_contains
operator in all databases because there can only be a JSON
null
within a JSON array. Since there cannot be a database
NULL
within a JSON array,
{ array_contains: null }
is not ambiguous.
For example:
model Log{
id Int@id
meta Json
}
Here is an example of using
AnyNull
:
import{Prisma}from'@prisma/client'
prisma.log.findMany({
where:{
data:{
meta:{
equals:Prisma.AnyNull,
},
},
},
})
Inserting
null
Values
This also applies to
create
,
update
and
upsert
. To insert a
null
value
into a
Json
field, you would write:
import{Prisma}from'@prisma/client'
prisma.log.create({
data:{
meta:Prisma.JsonNull,
},
})
And to insert a database
NULL
into a
Json
field, you would write:
import{Prisma}from'@prisma/client'
prisma.log.create({
data:{
meta:Prisma.DbNull,
},
})
Filtering by
null
Values
To filter by
JsonNull
or
DbNull
, you would write:
import{Prisma}from'@prisma/client'
prisma.log.findMany({
where:{
meta:{
equals:Prisma.AnyNull,
},
},
})
These
null enums
do not apply to MongoDB because MongoDB does not differentiate between a JSON
null
and a database
NULL
. They also do not apply to the
array_contains
operator in all databases because there can only be a JSON
null
within a JSON array. Since there cannot be a database
NULL
within a JSON array,
{ array_contains: null }
is not ambiguous.
Using
prisma-json-types-generator
First, install and configure
prisma-json-types-generator
.
Then, assuming you have a model like the following: