Scaum
Scaum

Reputation: 363

Slick: filter with Rep[Seq[T]]

I'm working on a Play! project (in Scala) for which I am using slick.

I'm having an issue when trying to filter a query on a jsonb column which contains several arrays.

For example my config column contains the following json:

{
 test1: {
   ...
 },
 test2: [
   {
    id: ...,
    bool: false
   },
   {
    id: ...,
    bool: true
   }
 ]
}

I want to query this table and select each row for which at least 1 of test2 elements has bool: true. (we may have approx 10 elements in test2).

I can try each element of test2 1 by 1:

    baseQuery.filter(a => a.config+>'test2'~>0+>>'bool' === "true" ||
                          a.config+>'test2'~>1+>>'bool' === "true" ||
                          ...
                    )

But this is obviously not a good solution.

I tried going with:

baseQuery.filter(a => (a.config+>'test2').arrayElements[JsArray].value...
                    )

But the Rep[JsArray] has no value method. I also tried using

arrayElements[Seq[JsValue]]

But I end up with a Rep[Seq[JsValue]] on which i cannot map/flatMap/exists/...

It has to stay a Query and not a DBIOAction so I don't have to reformat a lot of code...

Thanks everyone for your solutions/ideas !

Upvotes: 3

Views: 1653

Answers (1)

Scaum
Scaum

Reputation: 363

I found some "hackish" solution to solve my issue. I'm not entirely happy with it as I would have prefer to properly iterate over a Seq[JsValue] but here it is if someone has the same problem.

This is pretty straightforward, I'm using the +>> operator to get my JsValue as a string and then use the like to see if it contains the boolean I need set to true.

With the same (stupid) example as before, the solution would be:

baseQuery.filter(_.config+>>'test2' like "%\"bool\": true%")

This is probably not the best solution but it works for what I needed.

Upvotes: 0

Related Questions