Skip to Main Content
  • Questions
  • Odd behavior with predicate order, json_textcontains, and OR

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Sanjeev.

Asked: August 15, 2022 - 6:10 pm UTC

Last updated: August 16, 2022 - 3:29 am UTC

Version: 19.16.0.0.0

Viewed 1000+ times

You Asked

Database Version 19.16.0.0.0

I have a JSON document with "address", "address_name", and "state" keys among others. I'm searching for a user input in either "address" OR "address_name" in the JSON document. I also have an AND for the "state" key. Depending on the order of the predicate, I get results or no results. What am I missing here? My script is in LiveSQL

Also, is there a way to rank/score the results when using JSON_TEXTCONTAINS? If I wanted to use some of the other operators, like NDATA, SDATA, MDATA, FUZZY, WITHIN, or INPATH, do I use CONTAINS, or is it possible with JSON_TEXTCONTAINS. I would appreciate some example statements which show how to use these operators and SQL/JSON Path Expressions with JSON_TEXTCONTAINS.

Thanks

with LiveSQL Test Case:

and Connor said...

That looks like a bug to me. In particular, if you remove the "1=1" then things are fine. I'll log a bug for that.


SQL> create table jtc (
  2    rn number not null primary key
  3  , js clob not null
  4  , constraint jtc_json_ck check (js is json)
  5  );

Table created.

SQL>
SQL> insert into jtc (rn, js)
  2  values (1,'{
  3      "address_name": "Empire State Building",
  4      "address": "20 W 29th St",
  5      "city": "New York",
  6      "state": "NY",
  7      "postal_code": "10001",
  8      "country_code": "USA"
  9  }');

1 row created.

SQL>
SQL> commit;

Commit complete.

SQL>
SQL> create search index jtc_dx on jtc (js) for json
  2  parameters ('
  3  search_on text_value
  4  memory 100M
  5  sync (on commit)
  6  ');

Index created.

SQL>
SQL> select *
  2  from jtc
  3  where 1=1
  4  and ( json_textcontains(js,'$.state','ny%') )
  5  and ( json_textcontains(js,'$.address','em%') or json_textcontains(js,'$.address_name','em%') ) ;

        RN JS
---------- --------------------------------------------------------------------------------
         1 {
               "address_name": "Empire State Building",
               "address": "20 W 29th St",



SQL>
SQL> select *
  2  from jtc
  3  where 1=1
  4  and ( json_textcontains(js,'$.address','em%') or json_textcontains(js,'$.address_name','em%') )
  5  and ( json_textcontains(js,'$.state','ny%') ) ;

no rows selected

SQL>
SQL>
SQL> select *
  2  from jtc
  3  where ( json_textcontains(js,'$.state','ny%') )
  4  and ( json_textcontains(js,'$.address','em%') or json_textcontains(js,'$.address_name','em%') ) ;

        RN JS
---------- --------------------------------------------------------------------------------
         1 {
               "address_name": "Empire State Building",
               "address": "20 W 29th St",



SQL>
SQL> select *
  2  from jtc
  3  where ( json_textcontains(js,'$.address','em%') or json_textcontains(js,'$.address_name','em%') )
  4  and ( json_textcontains(js,'$.state','ny%') ) ;

        RN JS
---------- --------------------------------------------------------------------------------
         1 {
               "address_name": "Empire State Building",
               "address": "20 W 29th St",



SQL>


To my knowledge, you won't get scoring etc for a SEARCH index, but I *think* it is valid to fall back to standard Text index syntax to some degree.

SQL> select rn, js, score(0)
  2  from jtc
  3  where contains(js,'USA WITHIN state',0) > 1;

no rows selected

SQL> select rn, js, score(0)
  2  from jtc
  3  where contains(js,'USA WITHIN country_code',0) > 1;

        RN JS
---------- ---------------------------------------------------
  SCORE(0)
----------
         1 {
               "address_name": "Empire State Building",
               "address": "20 W 29th St",
               "city": "New York",
               "state": "NY",
               "postal_code": "10001",
               "country_code": "USA"
           }
         3



I'll double check with the Text team and amend this answer if they have any more info.

Is this answer out of date? If it is, please let us know via a Comment

More to Explore

Design

New to good database design? Check out Chris Saxon's full fundamentals class.