RESULT_SET
This procedure executes an XML or JSON query and generates a result set in XML or JSON.
The Result Set Interface can return data views that are difficult to express in SQL.
Complex RSI queries, especially those involving large SDATA, can be long-running. The longer a query runs, the more UNDO data is generated to support consistent read operations. This is because Oracle needs to preserve the data as it was at the start of the query to ensure the query’s consistency. On Windows systems, additional factors such as memory management and resource allocation can influence how Oracle manages UNDO. While the exact mechanisms can vary, it’s observed that RSI operations on Windows tend to have higher UNDO requirements. This increased demand can lead to ORA-08176 errors if the UNDO configuration is not adequately sized. To mitigate ORA-08176 errors in RSI query workloads on Windows, adjust UNDO Settings. Increase the UNDO_TABLESPACE size or optimize UNDO_MANAGEMENT parameter to accommodate the higher demands from larger SDATA processing.
See Also: Oracle Text Application Developer’s Guide for details on how to use the Result Set Interface
Syntax
CTX_QUERY.RESULT_SET (
index_name IN VARCHAR2,
query IN VARCHAR2,
result_set_descriptor IN CLOB,
result_set IN OUT NOCOPY CLOB,
part_name IN VARCHAR2 DEFAULT NULL,
format IN NUMBER DEFAULT CTX_QUERY.XML_FORMAT
);
index_name
Specify the index against which to execute the query.
query
Specify the query string.
result_set_descriptor
Specify the result set descriptor in XML or JSON. It describes what the result set should contain.
result_set
Specify the output result set. If this variable is NULL on input, a session-duration temporary lob will be allocated and returned to the user. The user is responsible for deallocating this temporary lob.
part_name
Specify the index partition name. If the index is global, part_name must be NULL. If the index is partitioned and part_name is not NULL, then the query will only be evaluated for the given partition. If the index is partitioned and part_name is NULL, then the query will be evaluated for all partitions.
format
Specify the format for the result set descriptor. Use CTX_QUERY.XML_FORMAT for XML format and CTX_QUERY.JSON_FORMAT for JSON format. The default is CTX_QUERY.XML_FORMAT.
The Input Result Set Descriptor
The result set descriptor is an XML message or JSON object which describes what to calculate for the result set. The elements present in the result set descriptor and the order in which they occur serve as a simple template, specifying what to include in the output result set. That is, there should be the list of hit rowids, then a count, then a token count, and so on. The attributes of the elements specify the parameters and options to the specific operations, such as number of hits in the list of rowids, estimate versus exact count, and so on.
The XML Format Input Result Set Descriptor
The result set descriptor itself is XML conforming to the following DTD:
<!DOCTYPE ctx_result_set_descriptor [
<!ELEMENT ctx_result_set_descriptor (hitlist?, group*, count?, collocates?)>
<!ELEMENT hitlist (rowid?, score?, sdata*, snippet*, sentiment?)>
<!ELEMENT group (count?, group_values?)>
<!ELEMENT count EMPTY>
<!ELEMENT rowid EMPTY>
<!ELEMENT score EMPTY>
<!ELEMENT sdata EMPTY>
<!ELEMENT group_values (value*)>
<!ELEMENT value EMPTY>
<!ELEMENT sentiment (item*)>
<!ELEMENT item EMPTY>
<!ELEMENT collocates EMPTY>
<!ATTLIST sentiment classifier CDATA "DEFAULT_CLASSIFIER">
<!ATTLIST item topic CDATA #REQUIRED>
<!ATTLIST item type (about|exact) "exact">
<!ATTLIST item agg (TRUE|FALSE) "FALSE">
<!ATTLIST item radius CDATA "50">
<!ATTLIST item max_inst CDATA "5">
<!ATTLIST item starttag CDATA #IMPLIED>
<!ATTLIST item endtag CDATA #IMPLIED>
<!ATTLIST collocates radius CDATA "20">
<!ATTLIST collocates max_words CDATA "10">
<!ATTLIST collocates use_tscore (TRUE|FALSE) "TRUE">
<!ATTLIST collocates use_hits CDATA "10">
<!ATTLIST group sdata CDATA #REQUIRED>
<!ATTLIST group topn CDATA #IMPLIED>
<!ATTLIST group bucketby CDATA #IMPLIED>
<!ATTLIST group sortby CDATA #IMPLIED>
<!ATTLIST group order CDATA #IMPLIED>
<!ATTLIST value id CDATA #IMPLIED>
<!ATTLIST hitlist start_hit_num CDATA #REQUIRED>
<!ATTLIST hitlist end_hit_num CDATA #REQUIRED>
<!ATTLIST hitlist order CDATA #IMPLIED>
<!ATTLIST count exact (TRUE|FALSE) "FALSE">
<!ATTLIST sdata name CDATA #REQUIRED>
<!ATTLIST snippet radius CDATA #IMPLIED>
<!ATTLIST snippet max_length CDATA #IMPLIED>
<!ATTLIST snippet starttag CDATA #IMPLIED>
<!ATTLIST snippet endtag CDATA #IMPLIED>
]>
The following is a description of the possible XML elements for the result set descriptor:
-
ctx_result_set_descriptorThis is the root element for the result set descriptor. The parent element is none, as are the available attributes.
The possible child elements are:
-
Zero or more
hitlistelements. -
Zero or more
groupelements. -
At most one
countelement.
-
-
groupThe
groupelement causes the generated result set to include a group breakdown. In other words, a breakdown of the results bySDATAsection values. The group element is also used to obtain facet counts for faceted navigation support. The parent element isctx_result_set_descriptor, and the available attributes are:-
sdataSpecifies the name of the
SDATAsection to use for grouping. It is required. -
bucketbyDetermines how group values are bucketed for counting. The
singleattribute displays each unique facet value along with its count. Starting with Oracle Database Release 21c, thecustomattribute value is also supported which displays a range of numeric facets along with their count. -
topnRestricts the maximum number of facet values that are returned. It sorts by descending group count by default. Valid attribute values are positive integers larger than zero.
-
sortbyValid attribute values are value and count. Value sorts using the value themselves, as appropriate for each data type. Count (default) sorts using the counts for each group.
-
orderOrder can be ascending or descending.
Possible child elements of
groupare:-
count -
range
-
-
hitlistThe
hitlistelement controls inclusion of a list of hit documents. The parent element isctx_result_set_descriptor, and the available attributes are:The possible attribute elements for
hitlistare:-
start_hit_numThis specifies the starting document hit to be included in the generated result set. This can be set to any positive integer less than or equal to 16000. For example, if
start_hit_numis 21, then the result set will include document hits starting from the 21st document hit. This element is required. -
end_hit_numThis specifies the last document hit to be included in the generated result set. This can be set to any positive integer less than or equal to 48000. For example, if
end_hit_numis 40, then the result set will include document hits up to the 40th document hit. This element is required. -
orderThis is an optional attribute that specifies the order for the documents in the generated result set. The value is a list similar to a SQL
ORDERBYstatement, except that, instead of column names, they can either beSCOREorSDATAsection names. In the following example,MYDATEandMYPRICEare theSDATAsection names:
-
(order = "SCORE DESC, MYDATE, MYPRICE DESC")
The possible child elements for `hitlist` are:
-
At most one
rowidelement. -
At most one
scoreelement. -
One or more
sdataelement. -
At most one
snippetelement. -
countThis element causes the generated result set to include a count of the number of hit documents. The parent elements are:
-
ctx_result_set_descriptor -
group
The available attributes for
countare:-
exactThis is to estimate mode. Set to
trueorfalse. It is required, and the default isfalse.
The possible child elements for
countare none. -
-
rowidThis child element causes the generated result set to include rowid information for each hit. The parent element is
hitlist. There are no attributes and no possible child elements. -
scoreThis child element causes the generated result set to include score information for each hit.
-
The parent element is
hitlist. -
There are no available attributes, and no possible child elements.
-
-
sdataThis child element causes the generated result set to include
sdatavalues for each hit.-
The parent element is
hitlist. -
The available attribute is
name. This specifies the name of thesdatasection. It is required. -
There are no child elements.
-
-
sentimentThis element controls the inclusion of sentiment classification results for each document returned as a part of the
hitlist. There can be only one sentiment element in thehitlistelement.The parent element is
hitlist.The attribute available for this element is
classifier, which specifies the sentiment classifier that is used to perform sentiment analysis. If no classifier is specified, then theCTXSYS.DEFAULT_SENTIMENT_CLASSIFIERis used. If a specified classifier is not available, then an error is displayed. -
itemThis element specifies keywords or concepts for which sentiment information must be fetched for the returned set of documents. Each
sentimentelement must contain at least one childitemelement. The maximum is 10 childitemelements. If you specify an emptyitemelement (without any attributes), it indicates that sentiment score for entire document must be returned.The parent element is
sentiment.The available attributes for
itemare:-
topicThis specifies the topic for which sentiment analysis must be performed.
-
typeIf this attribute value is set to
ABOUT, then the classifier treats the specified topic as a concept rather than a keyword. The default isEXACT. -
aggDetermines whether the sentiment score must be aggregated and presented as a single score for the entire document. The possible values are TRUE or FALSE. TRUE indicates that the per text segment scores will be aggregated and text segments will not be returned in the output resultset, only the aggregated score will be returned. The default value is FALSE.
-
radiusThis specifies the radius of the surrounding text to be identified during sentiment classification for that keyword. The default value is 50.
-
max_instThis specifies how many instances of text excerpts related to the specified topic must be analyzed for sentiment classification. The default value is 5.
-
starttagThis specifies the starting tag for topic highlighting.
-
endtagThis specifies the ending tag for topic highlighting.
-
-
collocatesThis element controls the generation of related keywords or concepts associated with the collection of documents retrieved by the query.
The parent element is
ctx_result_set_descriptor.The available attributes for
collocatesare:-
radiusThis specifies the radius of the surrounding text to be identified for collocates. The default value is 20.
-
max_wordsThis specifies the maximum number of collocates to return for the given query. The default value is 10.
-
use_tscoreThis specifies whether to use T-score for scoring the collocates. The possible values are TRUE or FALSE, with the default being TRUE.
Set this attribute to TRUE to identify collocates that are common tokens. Set this attribute to FALSE to identify collocates that emphasize unique words.
-
The Output Result Set XML
The output result set XML is XML conforming to the following DTD:
<!DOCTYPE ctx_result_set [
<!ELEMENT ctx_result_set (hitlist?, groups*, count? , collocates?)>
<!ELEMENT hitlist (hit*)>
<!ELEMENT hit (rowid?, score?, snippet*, sdata*, sentiment?)>
<!ELEMENT groups (group*)>
<!ELEMENT group (count?)>
<!ELEMENT count (#PCDATA)>
<!ELEMENT rowid (#PCDATA)>
<!ELEMENT score (#PCDATA)>
<!ELEMENT snippet (segment*)>
<!ELEMENT sdata (#PCDATA)>
<!ELEMENT sentiment (item*)>
<!ELEMENT item (segment*, score*, doc?)>
<!ELEMENT segment (segment_text?, segment_score?)>
<!ELEMENT segment_text (#PCDATA)>
<!ELEMENT segment_score (#PCDATA)>
<!ELEMENT doc (score?)>
<!ELEMENT collocates (collocation*)>
<!ELEMENT collocation (word?, score?)>
<!ELEMENT word (#PCDATA)>
<!ATTLIST item topic CDATA #REQUIRED>
<!ATTLIST groups sdata CDATA #REQUIRED>
<!ATTLIST group value CDATA #REQUIRED>
<!ATTLIST group range CDATA #IMPLIED>
<!ATTLIST group single CDATA #IMPLIED>
<!ATTLIST sdata name CDATA #REQUIRED>
The following is a description of the list of possible XML elements for the output result set:
-
ctx_result_setThis is the root element for the generated result set. There are no attributes. The parent is none. The possible child elements are:
-
At most one
hitlistelement. -
Zero or more
groupselements.
-
-
groupsThis delimits the start of a group breakdown section. The parent element is
ctx_result_set. The available attributes are:-
sdataThis is the name of the
sdatasection used for grouping.
The possible child elements are:
- Zero or more
groupelements.
-
-
groupThis delimits the start of a
GROUPBYvalue. The parent element is thegroupselement. The available attributes are:-
valueThis is the value of the
sdatasection.
The possible child elements are at most one
countelement. -
-
hitlistThis delimits the start of
hitlistinformation. The parent element isctx_result_set, while the children are zero or morehitelements. There are no attributes. -
hitThis delimits the start of the information for a particular document within a
hitlist. The parent element ishitlist, and there are no available attributes. The possible child elements are:-
Zero or one
rowidelements. -
Zero or one
scoreelement. -
Zero or one
sdataelement. -
Zero or one
snippetelement.
-
-
rowidThis is the rowid of the document, so the content is the rowid of the document. The parent element is the
hitelement. There are no child elements, and no available attributes. -
scoreThis is the score of the document. The parent element is the hit element. The content is the numeric score. There are no available attributes, and no possible child elements.
-
sdataThis is the
SDATAvalue or values for the document. The parent element is thehitelement, and the available attribute isname, which is the name of thesdatasection. There are no possible child elements available. The content is theSDATAsection value, which, forDATEvalues, is in the format “YYYY-MM-DD HH24:MI:SS”, depending upon the actual values being stored. -
countThis is the document hit count. The parent element is the
ctx_result_setelement or thegroupelement. It contains the numeric hit count, has no attributes, and no possible child elements. -
sentimentThis delimits the sentiment element for the
hitlistdocument. Its child element isitemand parent ishitlist. It contains no attributes in the output result set. -
itemThis delimits the
itemelement for thehitlistdocument. Parent element issentimentand child elements aresegment,score, anddoc. It has one attribute calledtopic. -
segmentThis delimits an instance of segment element in a hit. Parent element is
item. Child elements aresegment_textandsegment_score. It contains no attributes. -
segment_textThis specifies the text segment for the given item topic. Parent element is
segment. It has no child elements or attributes. -
segment_scoreThis specifies the sentiment score for the segment. Parent element is segment. It has no child elements or attributes.
-
scoreThis specifies the sentiment score for the document or for the parent item topic. When present within collocation it specifies the collocation score for the particular collocation keyword. Parent element is doc or collocation. It has no child elements or attributes
-
docThis denotes the sentiment score is for the entire document. Its parent element is
itemand child element isscore. It has no attributes. -
collocatesThis delimits the collocates element for the result set output. Parent element is
ctx_result_setand child element iscollocation. It has no attributes. -
collocationThis denotes a single collocation. Parent element is
collocatesand child elements arewordandscore. It has no attributes. -
wordThis specifies the collocates token. Its parent element is
collocation. It has no child elements or attributes.
Example
This call to CTX_QUERY.RESULT_SET with the specified XML result_set_descriptor will generate the following information in the form of XML:
-
top 5 hits displaying, score, rowid, author
SDATAsection value, and pubDateSDATAsection value, order by pubDateSDATAsection valueDESCand scoreDESC -
total doc hit count for the text query
-
counts group by pubDate
SDATAsection values -
counts group by author
SDATAsection values
declare
rs clob;
begin
dbms_lob.createtemporary(rs, true, dbms_lob.session);
ctx_query.result_set('docidx', 'oracle', '
<ctx_result_set_descriptor>
<count/>
<hitlist start_hit_num="1" end_hit_num="5" order="pubDate desc, score desc">
<score/>
<rowid/>
<sdata name="author"/>
<sdata name="pubDate"/>
</hitlist>
<group sdata="pubDate">
<count/>
</group>
<group sdata="author">
<count/>
</group>
</ctx_result_set_descriptor>
', rs);
dbms_lob.freetemporary(rs);
exception
when others then
dbms_lob.freetemporary(rs);
raise;
end;
/
The XML output store in the result set output clob will resemble the following:
<ctx_result_set>
<hitlist>
<hit>
<score>3</score><rowid>AAAPoEAABAAAMWsAAC</rowid>
<sdata name="AUTHOR">John</sdata>
<sdata name="PUBDATE">2001-01-03 00:00:00</sdata>
</hit>
<hit>
<score>3</score><rowid>AAAPoEAABAAAMWsAAG</rowid>
<sdata name="AUTHOR">John</sdata>
<sdata name="PUBDATE">2001-01-03 00:00:00</sdata>
</hit>
<hit>
<score>3</score><rowid>AAAPoEAABAAAMWsAAK</rowid>
<sdata name="AUTHOR">John</sdata>
<sdata name="PUBDATE">2001-01-03 00:00:00</sdata>
</hit>
<hit>
<score>3</score><rowid>AAAPoEAABAAAMWsAAO</rowid>
<sdata name="AUTHOR">John</sdata>
<sdata name="PUBDATE">2001-01-03 00:00:00</sdata>
</hit>
<hit>
<score>3</score><rowid>AAAPoEAABAAAMWsAAS</rowid>
<sdata name="AUTHOR">John</sdata>
<sdata name="PUBDATE">2001-01-03 00:00:00</sdata>
</hit>
</hitlist>
<count>100</count>
<groups sdata="PUBDATE">
<group value="2001-01-01 00:00:00"><count>25</count></group>
<group value="2001-01-02 00:00:00"><count>50</count></group>
<group value="2001-01-03 00:00:00"><count>25</count></group>
</groups>
<groups sdata="AUTHOR">
<group value="John"><count>50</count></group>
<group value="Mike"><count>25</count></group>
<group value="Steve"><count>25</count></group>
</groups>
</ctx_result_set>
The JSON Format Input Result Set Descriptor
The JSON format result set descriptor consists of $query, $search, and $facet parts. You can use the JSON format result set descriptor to query context indexes and JSON search index. It is of the following format:
{
"$query": <text query and filter conditions>,
"$search": <search result specifications>,
"$facet": <faceted result specifications>
}
-
$queryUse
$queryto specify a search query, the path constraints, and additional path based filter conditions. When$queryis specified, thequeryparameter ofCTX_QUERY.RESULT_SETprocedure is ignored.Note: The
$querypart is supported only when a JSON search index exists on the column. You can not specify the$querypart when there is an Oracle Text index.$queryis a subset of Simple Oracle Document Access (SODA) filter specification, also known as a query-by-example (QBE) or simply a filter. The following clauses are only supported:-
Contains Clause - A contains clause is a field followed by an object with one
$containsoperator, whose value is a string. It matches a document only if a string or number in the field value matches the string operand somewhere, including in array elements. Matching is Oracle Text full-text. You can use a contains clause only in the outermost condition of a QBE. You can also have multiple contains clauses only at the top level within a $and operator.For example, this QBE checks for a “name” field that contains the word “doe” and an “address” field that contains the number 10 or the string “10” as a word:
{ "$and" : [ {"name": { "$contains" : "doe" } }, { "address" : { "$contains" : "10" } } ] }
-
Note:
Use wildcard field steps (*) in the contains clause to include other path steps between the paths. For example: address.*.name Use descendent notation (..) in the contains clause to include descendant path steps between the paths. For example: address..name2 In this query, name2 is considered as a descendent of address and matches the address record of the table. You can use a $contains field condition only as a part of a simple $contains query or as a part of the outermost $and condition. You cannot use it as a part of a $or condition or an inner $and condition. Doing so results in an error.
-
Field-Condition Clause - A field-condition clause is JSON-object member whose field is not an operator and whose value is an object with one or more members, each of which is a condition-operator clause:
field : { condition-operator-clause ... }The following condition operators are only supported:
-
$eq - Matches document if field value equals operand value and the operand is a JSON scalar value. Also, matches document if field value is an array object and the operand value is an element of that array.
-
$gt - Matches document only if field value is greater than operand value. The operand must be a JSON number or string.
-
$gte - Matches document only if field value is greater than or equal to operand value. The operand must be a JSON number or string.
-
$lt - Matches document only if field value is less than operand value. The operand must be a JSON number or string.
-
$lte - Matches document only if field value is less than or equal to operand value. The operand must be a JSON number or string.
-
Note:
Wildcard field steps (*) and array steps ([ and ]) are not supported. To support field conditions on string values, a JSON search index with search_on text_value_string is required.
- Logical Combining Clause - A logical combining clause combines the effects of multiple non-empty filter conditions. A logical combining clause is a logical combining operator —
$andor$or— followed by a non-empty array of one or more non-empty filter conditions. The values of the operator clauses can only be numbers or string values.
The following is an example of a $query part with the supported clauses:
"$query" :
{
"$and" : [
{ "book.*.summary" : { "$contains" : "(Music or Song) and Dance" } },
{ "book.*.review" : { "$contains" : "(Good or excellent) and interesting" } },
{ "$or" : [
{ "book.rating" : { "$gte" :
4.5 } },
{ "$and" : [ { "book.price" : { "$lte" : 100 } }, { "book.author" : { "$eq" : "Doe" } } ] }
]
]
}
-
$searchUse
$searchto display the score ranked search results and their count. For a non-JSON Oracle Text full-text index, you can also specify theSDATAsections to project for the search results.You can use the following attributes:
-
startandend- Specify the range of the search result. For example, forstart=1andend=10,the first 10 documents are returned. -
project- Specify the list ofSDATAsections to project for the search results. This attribute is supported only for a non-JSON Oracle Text full-text index.
-
-
$facetUse
$facetto specify the facets for various paths of a JSON document orSDATAsections of a context indexed document. Facets bucketed by a single unique value and facets per user specified range buckets are supported. The facets can also be one of the aggregations likeCOUNT,MIN,etc.You can specify a facet object in the following ways:
-
A field as a string or numeric value for which the output has facet group counts for each single unique value of the specified field:
{ "$uniqueCount": { "path/sdata" : field, "type" (Optional) : "string/number" } }where:
-
fieldrefers to a SODA path for querying using a JSON search index when you usepathandSDATAsection name for querying using a context index when you usesdata. -
typeis eitherstring(default) ornumber. When you are usingsdata, thetypeparameter is not allowed as eachsdataalready has a predefined type.
-
-
A field only for string values when using a JSON search index where
fieldrefers to a SODA path for querying using a JSON search index:{ "$uniqueCount": field } -
A field for computing aggregations on facet groups using bucket ranges:
{ "$op : { "path/sdata" : field , "bucket <Optional>" : [ { "$gt/$gte (Optional)" : <lower bound 1>, "$lt/$lte (Optional)" : <upper bound 1>}, ... ], "type" <Optional> : "string/number" } }where:
-
$opis one of$sum,$min,$max,$avg, or$count. -
fieldrefers to a SODA path for querying using a JSON search index when you usepathandSDATAsection name for querying using a context index when you usesdata. -
Each range bucket must have at-most one lower bound (
$gtor$gte) and upper bound ($ltor$lte). -
typeis eithernumber(default) orstring. When you are usingsdata, thetypeparameter is not allowed as eachsdataalready has a predefined type.
-
Note:
$sumand$avgaggregations are only supported when the value oftypeparameter isnumberorsdatais of number type. You can only use$count,$min, and$maxforstringtype.-
A field only for computing aggregations on numeric facets without using bucket ranges:
{ "$op" : <field> }$opis one of$sum,$min,$max,$avg, or$count.
The following is an example for
$facetpart:"$facet": [ { "$sum" : { "path" : "book.price", "bucket" : [ { "$lt" : 100 }, { "$gte" : 100, "$lt" : 150 }, { "$gte" : 150 } ] } }, { "$count" : { "path" : "book.author", "bucket" : [ {"$lt" : "G"}, {"$gte" : "G", "$lt" : "S"}, {"$gte" : "S"} ], "type" : "string" } }, { "$uniqueCount" : "book.author" }, { "$uniqueCount " : { "path" : "book.rating", "type" : "number" } }, { "$avg" : "book.sales" } { "$min" : "book.name", "type" : "string" } ]This example generates the following:
-
Sum of prices for each bucket range of the specified
book.price -
Total number of authors in the given specified ranges
-
A group count of every unique value of
book.author -
A group count of every
book.ratingtreating the rating as a number -
Average of the book sales for all the books that satisfied the query
-
The author’s name that is lexicographically smallest
Note: To support facets on string values, a JSON search index with
search_on text_value_stringis required. -
The JSON Format Result Set Output
The JSON format result set output is a JSON object that consists of the following parts:
"$count" : number
"$hit" : [ <hit_object_1>, ..., <hit_object_i> , ... ]
"$facet": [ <facet_object_1>, ..., <facet_object_i>, ...]
The following is a description of the list of possible JSON objects for the output result set:
-
$countThe
$countJSON object shows the total number of hits for the query. -
$hitThe
$hitJSON object shows an array of search hit objects sorted in descending order of search score depending on how many hits were specified usingstartandendin the$searchpart of the input query. It has the following attributes:-
scoreThe
scoreattribute shows the score information for each hit. -
rowidThe
rowidattribute shows the rowid information for each hit. -
projectThe
projectattribute shows thesdatavalues that were specified in the$searchpart of the input query. Theprojectattribute is supported only for a non-JSON Oracle Text full-text index.
-
-
$facetThe
$facetJSON object shows an array of facet responses for every facet specified in the$facetpart of the input query.For enumerating counts for each unique input string or numeric value, the output is of the following format:
{ "<field>" : [ ..., { "value" : <value_i>, "$uniqueCount" : <group_count_i>}, ... ]}For enumerating counts for the buckets specified in input to compute aggregations for facet groups, the output is of the following format:
{ "<field>" : [ ..., { "bucket" : <bucket_object_i>, "<op>" : <group_count_i>}, ... ]}Note: For bucket outputs, if either lower bound (
$gtor$gte) or upper bound ($ltor$lte) are not specified in the input, then the minimum or maximum value is discovered and displayed in the output.For enumerating counts for computing aggregations on numeric facets without using buckets, the output is of the following format:
{ "<field>" : { "<op>" : <actual_value of the aggregation> } }
Example 12-1 Using the JSON format Result Set Interface with CONTEXT Index
This example shows you how to use the JSON format result set interface with CONTEXT index.
Create a table and populate it with values:
drop table zebra_table;
create table zebra_table(id number, details clob);
INSERT INTO zebra_table
VALUES (1,' Zebra details : <price>2000</price><price>1000</price>
<name>Storm</name>
<stripes>Dark</stripes><stripes>Light</stripes>
<handler>Bob</handler>
<sold>true</sold>');
INSERT INTO zebra_table
VALUES (2,' Zebra details : <rating>5</rating> <price>1000</price>
<name>Snowy</name>
<stripes>Light</stripes><stripes>Grey</stripes>
<handler>Jane Doe</handler>
<sold>true</sold>');
INSERT INTO zebra_table
VALUES (3,' Zebra details : <rating>4.5</rating> <price>3000</price>
<name>Zigs</name>
<stripes>Grey</stripes><stripes>Dark</stripes>
<handler>Jane Doe</handler>
<sold>false</sold>');
INSERT INTO zebra_table
VALUES (4,' Zebra details : <rating>4.5</rating> <price>3000</price>
<name>Zigs</name>
<stripes>Grey</stripes><stripes>Dark</stripes>
<handler>Jane Doe</handler> <sold></sold>');
Create a section group named mysecgrp and enable the optimized_for search attribute for each column to be treated as a facet:
exec ctx_ddl.drop_section_group ('mysecgrp')
exec ctx_ddl.create_section_group ('mysecgrp', 'BASIC_SECTION_GROUP')
exec ctx_ddl.add_sdata_section ('mysecgrp', 'rating', 'rating', 'NUMBER')
exec ctx_ddl.set_section_attribute('mysecgrp', 'rating', 'optimized_for', 'search')
exec ctx_ddl.add_sdata_section ('mysecgrp', 'price', 'price', 'NUMBER')
exec ctx_ddl.set_section_attribute('mysecgrp', 'price', 'optimized_for', 'search')
exec ctx_ddl.add_sdata_section ('mysecgrp', 'name', 'name', 'VARCHAR2')
exec ctx_ddl.set_section_attribute('mysecgrp', 'name', 'optimized_for', 'search')
exec ctx_ddl.add_sdata_section ('mysecgrp', 'stripes', 'stripes', 'VARCHAR2')
exec ctx_ddl.set_section_attribute('mysecgrp', 'stripes', 'optimized_for', 'search')
exec ctx_ddl.add_sdata_section ('mysecgrp', 'handler', 'handler', 'VARCHAR2')
exec ctx_ddl.set_section_attribute('mysecgrp', 'handler', 'optimized_for', 'search')
exec ctx_ddl.add_sdata_section ('mysecgrp', 'sold', 'sold', 'VARCHAR2')
exec ctx_ddl.set_section_attribute('mysecgrp', 'sold', 'optimized_for', 'search')
Create a CONTEXT index on details and specify the preferences by using the parameters clause:
create index zebra_idx on zebra_table(details)
indextype is ctxsys.context
parameters('section group mysecgrp');
A call to CTX_QUERY.RESULT_SET with the specified JSON result_set_descriptor generates the following information in the form of JSON:
-
Rowids, names, and handlers for the first two hits
-
Total number of unique zebra names
-
Total number of sold and unsold zebras
-
Total number of zebras according to their prices
-
Sum of prices and average rating between a price range for the total hits and unique counts based on the sum of prices and average rating
-
Total number of zebras grouped by their handler name within certain ranges
variable rs_output clob;
declare
qry varchar2(4000);
rs_descriptor clob;
begin
qry := 'zebra details';
rs_descriptor := '
{
"$search" : { "start" : 1, "end" : 2, "project" : [ "name", "handler" ] },
"$facet" : [
{ "$uniqueCount" : "name" },
{ "$uniqueCount" : "sold" },
{ "$uniqueCount" : { "sdata" : "price" } },
{ "$sum" : { "sdata" : "price",
"bucket" :
[ { "$lt" : 3000 }, { "$gte" : 3000 } ]
}
},
{ "$avg" : "rating" },
{
"$count" : { "sdata" : "handler",
"bucket" :
[ { "$lte" : "C" }, { "$gt" : "C" } ]
}
}
]
}
';
dbms_lob.createtemporary( :rs_output, true );
ctx_query.result_set( 'zebra_idx', qry, rs_descriptor, :rs_output,
format => CTX_QUERY.JSON_FORMAT );
end;
/
select json_query(:rs_output, '$' pretty) from dual;
The following is output:
{
"$count" : 4,
"$hit" :
[
{
"score" : 3,
"rowid" : "AAASxXAABAAAY95AAA",
"project" :
{
"NAME" : "Storm",
"HANDLER" : "Bob"
}
},
{
"score" : 3,
"rowid" : "AAASxXAABAAAY95AAB",
"project" :
{
"NAME" : "Snowy",
"HANDLER" : "Jane Doe"
}
}
],
"$facet" :
[
{
"NAME" :
[
{
"value" : "Zigs",
"$uniqueCount" : 2
},
{
"value" : "Snowy",
"$uniqueCount" : 1
},
{
"value" : "Storm",
"$uniqueCount" : 1
}
]
},
{
"SOLD" :
[
{
"value" : "true",
"$uniqueCount" : 2
},
{
"value" : "false",
"$uniqueCount" : 1
}
]
},
{
"PRICE" :
[
{
"value" : 1000,
"$uniqueCount" : 2
},
{
"value" : 3000,
"$uniqueCount" : 2
},
{
"value" : 2000,
"$uniqueCount" : 1
}
]
},
{
"PRICE" :
[
{
"bucket" :
{
"$gte" : 1000,
"$lt" : 3000
},
"$sum" : 4000
},
{
"bucket" :
{
"$gte" : 3000,
"$lte" : 3000
},
"$sum" : 6000
}
]
},
{
"RATING" :
{
"$avg" : 4.66666666666666666667
}
},
{
"HANDLER" :
[
{
"bucket" :
{
"$gte" : "Bob",
"$lte" : "C"
},
"$count" : 1
},
{
"bucket" :
{
"$gt" : "C",
"$lte" : "Jane Doe"
},
"$count" : 3
}
]
}
]
}
Example 12-2 Using the JSON format Result Set Interface with JSON Search Index
This example shows you how to use the JSON format result set interface with JSON search index.
Create a table and populate it with values:
drop table zebra_table;
create table zebra_table(id number, details clob check(details is json));
INSERT INTO zebra_table
VALUES (1,'{ "zebra" : { "price" : [2000,1000],
"name" : "Storm",
"stripes" : ["Dark","Light"],
"handler" : "Bob", "sold" : true }}');
INSERT INTO zebra_table
VALUES (2,'{ "zebra" : { "rating": 5, "price" : 1000,
"name" : "Zigzag",
"stripes" : ["Light","Grey"],
"handler" : "Jane Doe", "sold" : "true" }}');
INSERT INTO zebra_table
VALUES (3,'{ "zebra" : { "rating": 4.5, "price" : 3000,
"name" : "Zigs",
"stripes" : ["Grey","Dark"],
"handler" : "Jane Doe", "sold" : false }}');
INSERT INTO zebra_table
VALUES (4,'{ "zebra" : { "rating": "4.5", "price" : "3000",
"name" : "Zigs",
"stripes" : ["Grey","Dark"],
"handler" : "Jane Doe", "sold" : null }}');
Create a JSON search index on details and specify the preferences by using the parameters clause:
create search index zebra_idx on zebra_table(details) for json
parameters('search_on text_value_string');
A call to CTX_QUERY.RESULT_SET with the specified JSON result_set_descriptor generates the following information in the form of JSON:
-
Total number of zebras that have names which satisfy the given condition
-
Rowids for the first two hits that have names which satisfy the given condition
-
Total number of unique zebra names
-
Total number of sold and unsold zebras
-
Total number of zebras according to their prices
-
Sum of prices and average rating between a price range for the total hits and unique counts based on the sum of prices and average rating
-
Total number of zebras grouped by their handler name within certain ranges
variable rs_output clob;
declare
rs_descriptor clob;
begin
rs_descriptor := '
{
"$query" : { "zebra.*.name" : { "$contains" : "sto% or zig%" } },
"$search" : { "start" : 1, "end" : 2 },
"$facet" : [
{ "$uniqueCount" : "zebra.name" },
{ "$uniqueCount" : "zebra.sold" },
{ "$uniqueCount" :
{ "path" : "zebra.price", "type" : "number" }
},
{ "$sum" : { "path" : "zebra.price",
"bucket" :
[ { "$lt" : 3000 }, { "$gte" : 3000 } ]
}
},
{ "$avg" : "zebra.rating" },
{
"$count" : { "path" : "zebra.handler",
"type" : "string",
"bucket" :
[ { "$lte" : "C" }, { "$gt" : "C" } ]
}
}
]
}
';
dbms_lob.createtemporary( :rs_output, true );
ctx_query.result_set( 'zebra_idx', null, rs_descriptor, :rs_output,
format => CTX_QUERY.JSON_FORMAT );
end;
/
select json_query(:rs_output, '$' pretty) from dual;
The following is output:
{
"$count" : 4,
"$hit" :
[
{
"score" : 4,
"rowid" : "AAASwtAABAAAY95AAB"
},
{
"score" : 4,
"rowid" : "AAASwtAABAAAY95AAC"
}
],
"$facet" :
[
{
"zebra.name" :
[
{
"value" : "Zigs",
"$uniqueCount" : 2
},
{
"value" : "Zigzag",
"$uniqueCount" : 1
},
{
"value" : "Storm",
"$uniqueCount" : 1
}
]
},
{
"zebra.sold" :
[
{
"value" : "true",
"$uniqueCount" : 2
},
{
"value" : "null",
"$uniqueCount" : 1
},
{
"value" : "false",
"$uniqueCount" : 1
}
]
},
{
"zebra.price" :
[
{
"value" : 1000,
"$uniqueCount" : 2
},
{
"value" : 3000,
"$uniqueCount" : 2
},
{
"value" : 2000,
"$uniqueCount" : 1
}
]
},
{
"zebra.price" :
[
{
"bucket" :
{
"$gte" : 1000,
"$lt" : 3000
},
"$sum" : 4000
},
{
"bucket" :
{
"$gte" : 3000,
"$lte" : 3000
},
"$sum" : 6000
}
]
},
{
"zebra.rating" :
{
"$avg" : 4.66666666666666666667
}
},
{
"zebra.handler" :
[
{
"bucket" :
{
"$gte" : "Bob",
"$lte" : "C"
},
"$count" : 1
},
{
"bucket" :
{
"$gt" : "C",
"$lte" : "Jane Doe"
},
"$count" : 3
}
]
}
]
}
Limitations and Restrictions
The following limitations and restrictions apply for RESULT_SET.
-
The Result Set Interface (RSI) is not supported with Virtual Private Database. (VPD is supported with the regular
CONTAINSquery, but not with RSI.) -
In order to execute the function, you must be able to query the base table.
-
If a VPD policy is active on the base table, the documents portion of the result set will not show any documents to which you are not entitled.
-
When a VPD policy is being used, aggregate measures such as count may not be accurate.
See Also:
Oracle Text Application Developer’s Guide for information on the XML and JSON Result Set Interfaces Oracle Text Application Developer’s Guide for more information on faceted navigation Oracle Database Introduction to Simple Oracle Document Access (SODA) for more information on SODA filter specifications