I can't seem to able to wrap my head around this.
I got several translations in a json column called text
, and I want to select only those records that have not empty translations for a specific language (not set, or not null
).
I struggle in creating a query that doesn't return a record if the value is set to null
.
Here are some text
column json values, and I need a query that returns only the first record in this example, where I have a translation for the fr
value:
text: "{"de": "danke", "fr": "merci"}"
text: "{"de": "hallo", "fr": null}"
text: "{"de": "und"}"
Here is what I tried so far:
parent::whereRaw( 'JSON_EXTRACT(text, "$.fr") is not null' )->get();
-> returns
text: "{"de": "danke", "fr": "merci"}"
text: "{"de": "hallo", "fr": null}"
Bummer. It skips the record where fr
is not set at all (that's ok), but keeps selecting the record where fr
is set to null
. So, I need to adjust the query to exclude the record with "fr": null
Let's approach this step by step. When I try a positive match search for a string like this:
parent::whereRaw( 'JSON_EXTRACT(text, "$.fr") = "merci"' )->get();
-> returns
text: "{"de": "danke", "fr": "merci"}"
That is correct. Now, it would seem easy to find a way to switch this around and exclude records with "fr": null
. But no luck.
parent::whereRaw( 'JSON_EXTRACT(text, "$.fr") <> "merci"' )->get();
-> returns only the record where fr
is set, but is not equal to merci
. It skips the record where fr
is not set.
text: "{"de": "hallo", "fr": null}"
Let's try to exclude records where fr is set to null. But no luck either:
parent::whereRaw( 'JSON_EXTRACT(text, "$.fr") <> "null"' )->get();
-> returns
text: "{"de": "danke", "fr": "merci"}"
text: "{"de": "hallo", "fr": null}"
Or,
parent::whereRaw( 'JSON_EXTRACT(text, "$.fr") <> null' )->get();
-> returns an empty result.
How the heck can I exclude fr
values that are not set or are set to null
?