To understand the value of this feature, consider a JSON Search Index created using the traditional SEARCH_ON TEXT_VALUE_STRING option. Such an index provides excellent query performance because it indexes text values, numeric values, and timestamp values across all supported JSON paths. As a result, both full-text searches and value-based predicates can be efficiently answered through the same index. Queries that search for a product identifier, a quantity value, or a text attribute such as a product title can all take advantage of index access paths.
2 on my_demo(c2)
3 for json parameters(' search_on TEXT_VALUE_STRING ');
demo@ADB26AI> set autotrace traceonly exp
demo@ADB26AI>
demo@ADB26AI> select *
2 from my_demo
3 where json_exists( c2, '$.products[*]?(@.id.number() == 72)' );
----------------------------------------------------------
Plan hash value: 2005405343
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 18200 | 488 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID | MY_DEMO | 25 | 18200 | 488 (0)| 00:00:01 |
| 2 | SORT CLUSTER BY ROWID BATCHED| | | | 4 (0)| 00:00:01 |
|* 3 | DOMAIN INDEX | MY_DEMO_IDX | | | 4 (0)| 00:00:01 |
---------------------------------------------------
'$.products[*]?(@.id.number() == 72)' /* json_path_str $.products[*]?(@.id.number()
== 72) */ FALSE ON ERROR TYPE(LAX) )=1)
3 - access("CTXSYS"."CONTAINS"("MY_DEMO"."C2" /*+ LOB_BY_VALUE */
,'(sdata(FNUM_6AA7829B12A1ECA7231B4272D111B8B4_id = 72 ))')>0)
demo@ADB26AI> select *
2 from my_demo
3 where json_exists( c2, '$.products[*]?(@.quantity.number() == 42)' );
----------------------------------------------------------
Plan hash value: 2005405343
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 18200 | 488 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID | MY_DEMO | 25 | 18200 | 488 (0)| 00:00:01 |
| 2 | SORT CLUSTER BY ROWID BATCHED| | | | 4 (0)| 00:00:01 |
|* 3 | DOMAIN INDEX | MY_DEMO_IDX | | | 4 (0)| 00:00:01 |
---------------------------------------------------
'$.products[*]?(@.quantity.number() == 42)' /* json_path_str
$.products[*]?(@.quantity.number() == 42) */ FALSE ON ERROR TYPE(LAX) )=1)
3 - access("CTXSYS"."CONTAINS"("MY_DEMO"."C2" /*+ LOB_BY_VALUE */
,'(sdata(FNUM_409E93841EA61DD3F60D03041A92157A_quantity = 42 ))')>0)
2 from my_demo
3 where json_textcontains( c2,'$.products.title','Charger SXT RWD');
----------------------------------------------------------
Plan hash value: 2005405343
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2500 | 1777K| 488 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | MY_DEMO | 2500 | 1777K| 488 (0)| 00:00:01 |
| 2 | SORT CLUSTER BY ROWID BATCHED| | | | 4 (0)| 00:00:01 |
|* 3 | DOMAIN INDEX | MY_DEMO_IDX | | | 4 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
---------------------------------------------------
RWD) INPATH (/products/title)')>0)
2 from user_segments
3 where segment_name like '%MY_DEMO_IDX%';
----------
2483.63
2 parameters( ' ADD search_on value(number) include ($.products.id) ' );
2 from user_segments
3 where segment_name like '%MY_DEMO_IDX%';
----------
2556.69
2 from my_demo
3 where json_exists( c2, '$.products[*]?(@.id.number() == 72)' );
----------------------------------------------------------
Plan hash value: 2005405343
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 18200 | 488 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID | MY_DEMO | 25 | 18200 | 488 (0)| 00:00:01 |
| 2 | SORT CLUSTER BY ROWID BATCHED| | | | 4 (0)| 00:00:01 |
|* 3 | DOMAIN INDEX | MY_DEMO_IDX | | | 4 (0)| 00:00:01 |
---------------------------------------------------
'$.products[*]?(@.id.number() == 72)' /* json_path_str $.products[*]?(@.id.number()
== 72) */ FALSE ON ERROR TYPE(LAX) )=1)
3 - access("CTXSYS"."CONTAINS"("MY_DEMO"."C2" /*+ LOB_BY_VALUE */
,'(sdata(FNUM_6AA7829B12A1ECA7231B4272D111B8B4_id = 72 ))')>0)
2 from my_demo
3 where json_exists( c2, '$.products[*]?(@.quantity.number() == 42)' );
----------------------------------------------------------
Plan hash value: 3804406768
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 50000 | 34M| 738 (40)| 00:00:01 |
| 1 | RESULT CACHE | g9xkr5g0q79r37y3xw9y29gvmm | 50000 | 34M| 738 (40)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| MY_DEMO | 50000 | 34M| 738 (40)| 00:00:01 |
-------------------------------------------------------------------------------------------------
---------------------------------------------------
'$.products[*]?(@.quantity.number() == 42)' /* json_path_str
$.products[*]?(@.quantity.number() == 42) */ FALSE ON ERROR TYPE(LAX) )=1)
------------------------------------------------------
from my_demo
where json_exists( c2, '$.products[*]?(@.quantity.number() == 42)' )"
2 from my_demo
3 where json_textcontains( c2,'$.products.title','Charger SXT RWD');
----------------------------------------------------------
Plan hash value: 2005405343
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2500 | 1777K| 488 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | MY_DEMO | 2500 | 1777K| 488 (0)| 00:00:01 |
| 2 | SORT CLUSTER BY ROWID BATCHED| | | | 4 (0)| 00:00:01 |
|* 3 | DOMAIN INDEX | MY_DEMO_IDX | | | 4 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
---------------------------------------------------
2 parameters( ' REMOVE search_on text_value(varchar2) ' );
2 from user_segments
3 where segment_name like '%MY_DEMO_IDX%';
----------
388.81
2 from my_demo
3 where json_exists( c2, '$.products[*]?(@.id.number() == 72)' );
----------------------------------------------------------
Plan hash value: 2005405343
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 18200 | 488 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID | MY_DEMO | 25 | 18200 | 488 (0)| 00:00:01 |
| 2 | SORT CLUSTER BY ROWID BATCHED| | | | 4 (0)| 00:00:01 |
|* 3 | DOMAIN INDEX | MY_DEMO_IDX | | | 4 (0)| 00:00:01 |
---------------------------------------------------
'$.products[*]?(@.id.number() == 72)' /* json_path_str $.products[*]?(@.id.number()
== 72) */ FALSE ON ERROR TYPE(LAX) )=1)
3 - access("CTXSYS"."CONTAINS"("MY_DEMO"."C2" /*+ LOB_BY_VALUE */
,'(sdata(FNUM_6AA7829B12A1ECA7231B4272D111B8B4_id = 72 ))')>0)
2 from my_demo
3 where json_exists( c2, '$.products[*]?(@.quantity.number() == 42)' );
----------------------------------------------------------
Plan hash value: 3804406768
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 50000 | 34M| 738 (40)| 00:00:01 |
| 1 | RESULT CACHE | g9xkr5g0q79r37y3xw9y29gvmm | 50000 | 34M| 738 (40)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| MY_DEMO | 50000 | 34M| 738 (40)| 00:00:01 |
-------------------------------------------------------------------------------------------------
---------------------------------------------------
'$.products[*]?(@.quantity.number() == 42)' /* json_path_str
$.products[*]?(@.quantity.number() == 42) */ FALSE ON ERROR TYPE(LAX) )=1)
------------------------------------------------------
from my_demo
where json_exists( c2, '$.products[*]?(@.quantity.number() == 42)' )"
2 from my_demo
3 where json_textcontains( c2,'$.products.title','Charger SXT RWD');
*
ERROR at line 2:
ORA-40467: JSON_TEXTCONTAINS() cannot be evaluated without a JSON-enabled context index
Help: https://docs.oracle.com/error-help/db/ora-40467/
2 parameters( ' REPLACE search_on value(number) include ($.products.id) ' );
2 from user_segments
3 where segment_name like '%MY_DEMO_IDX%';
----------
383.44
2 from my_demo
----------------------------------------------------------
Plan hash value: 2005405343
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 18200 | 488 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID | MY_DEMO | 25 | 18200 | 488 (0)| 00:00:01 |
| 2 | SORT CLUSTER BY ROWID BATCHED| | | | 4 (0)| 00:00:01 |
|* 3 | DOMAIN INDEX | MY_DEMO_IDX | | | 4 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
---------------------------------------------------
'$.products[*]?(@.id.number() == 72)' /* json_path_str $.products[*]?(@.id.number()
== 72) */ FALSE ON ERROR TYPE(LAX) )=1)
3 - access("CTXSYS"."CONTAINS"("MY_DEMO"."C2" /*+ LOB_BY_VALUE */
2 from my_demo
3 where json_exists( c2, '$.products[*]?(@.quantity.number() == 42)' );
----------------------------------------------------------
Plan hash value: 3804406768
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 50000 | 34M| 738 (40)| 00:00:01 |
| 1 | RESULT CACHE | g9xkr5g0q79r37y3xw9y29gvmm | 50000 | 34M| 738 (40)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| MY_DEMO | 50000 | 34M| 738 (40)| 00:00:01 |
-------------------------------------------------------------------------------------------------
---------------------------------------------------
'$.products[*]?(@.quantity.number() == 42)' /* json_path_str
$.products[*]?(@.quantity.number() == 42) */ FALSE ON ERROR TYPE(LAX) )=1)
------------------------------------------------------
from my_demo
where json_exists( c2, '$.products[*]?(@.quantity.number() == 42)' )"
2 from my_demo
3 where json_exists( c2,'$.products[*]?(@.title == "Charger SXT RWD")');
----------------------------------------------------------
Plan hash value: 3804406768
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 50000 | 34M| 738 (40)| 00:00:01 |
| 1 | RESULT CACHE | bdzdkjsz7xptdbx5kjyaykf3yf | 50000 | 34M| 738 (40)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| MY_DEMO | 50000 | 34M| 738 (40)| 00:00:01 |
-------------------------------------------------------------------------------------------------
---------------------------------------------------
'$.products[*]?(@.title == "Charger SXT RWD")' /* json_path_str
$.products[*]?(@.title.string() == "Charger SXT RWD") */ FALSE ON ERROR TYPE(LAX) )=1)
------------------------------------------------------
from my_demo
where json_exists( c2,'$.products[*]?(@.title == "Charger SXT RWD")')"