15.3 Querying Facets by Using the Result Set Interface
Starting with Oracle Database Release 18c, the group-counting operation for a specified list of facets is provided. You can obtain the group counts for each single value by using the bucketby
attribute with its value set to single.
The topn,
sortby,
and order
attributes are also supported. Starting with Oracle Database Release 21c, you can obtain the group counts for a range of numeric and variable character facet values by using the range
element, which is a child element of the group
element.
bucketby Attribute
Valid attributes are single
and custom.
-
The 'single' mode produces a list of all unique values for the facet and a document count for each value.
-
The 'custom' mode produces document counts for a range of numeric values.
count Element (Single Count)
In the following example, a few rows are inserted into the mytab
table. Some rows have two values for the facet <B>,
and some rows have a single value.
begin
insert into mytab values (1, '<B>1.234</B><B>5</B>');
insert into mytab values (2, '<B>1.432</B>');
insert into mytab values (3, '<B>2.432</B><B>6</B>');
insert into mytab values (4, '<B>2.432</B>');
end;
Single counts show each unique value and the number of documents that have this value:
<ctx_result_set>
<groups sdata="SEC01">
<group value="2.432"><count>2</count></group>
<group value="1.234"><count>1</count></group>
<group value="5"><count>1</count></group>
<group value="6"><count>1</count></group>
<group value="1.432"><count>1</count></group>
</groups>
</ctx_result_set>
If document 1 is deleted, you see the following result:
<ctx_result_set>
<groups sdata="SEC01">
<group value="2.432"><count>2</count></group>
<group value="6"><count>1</count></group>
<group value="1.432"><count>1</count></group>
</groups>
</ctx_result_set>
range Element
The range
element supports start, greaterthan, end,
and lessthan
attributes. The start
and greaterthan
attributes specify the beginning value for the range. The end
and lessthan
attributes specify the ending value for the range.
Ranges can overlap each other. For example, <range start="1" end="2"/>
and <range start="2" end="3"/>.
Ranges can also be open ended. For example, you can specify only the start value or the end value. If you do not specify the attributes of the range
element, all results are returned.
Example 15-2 Obtaining Group Counts for a Range of Facets
Create a table named products
and populate it:
drop table products;
create table products(name varchar2(60), vendor varchar2(60), rating number, price number);
insert all
into products values ('cherry red shoes', 'first vendor', 5, 129)
into products values ('bright red shoes', 'first vendor', 4, 109)
into products values ('more red shoes', 'second vendor', 5, 129)
into products values ('shoes', 'third vendor', 5, 109)
into products values ('dark red shoes', 'fourth vendor', 3, 98)
into products values ('light red shoes', 'fifth vendor', 2, 49)
select * from dual;
Create a MULTI_COLUMN_DATASTORE
preference named ds
to bring various other columns into the index (name)
to be used as facets:
exec ctx_ddl.drop_preference ('ds')
exec ctx_ddl.create_preference('ds', 'MULTI_COLUMN_DATASTORE')
exec ctx_ddl.set_attribute ('ds', 'COLUMNS', 'name, vendor, rating, price')
Create a section group named sg
and enable the optimized_for search
attribute for each column to be treated as a facet:
exec ctx_ddl.drop_section_group ('sg')
exec ctx_ddl.create_section_group ('sg', 'BASIC_SECTION_GROUP')
exec ctx_ddl.add_sdata_section ('sg', 'rating', 'rating', 'NUMBER')
exec ctx_ddl.add_sdata_section ('sg', 'price', 'price', 'NUMBER')
exec ctx_ddl.add_sdata_section ('sg', 'vendor', 'vendor', 'VARCHAR2')
exec ctx_ddl.set_section_attribute('sg', 'rating', 'optimized_for', 'SEARCH')
exec ctx_ddl.set_section_attribute('sg', 'price', 'optimized_for', 'SEARCH')
exec ctx_ddl.set_section_attribute('sg', 'vendor', 'optimized_for', 'SEARCH')
Create an index on name
and specify the preferences by using the parameters
clause:
create index mytab_idx on products (name)
indextype is ctxsys.context
parameters ('datastore ds section group sg');
Query for a product name, ‘red shoes’ by setting the bucketby
attribute to custom
and provide the values for the range
element:
set long 500000
set pagesize 0
variable displayrs clob;
declare
rs clob;
begin
ctx_query.result_set('mytab_idx', 'red shoes', '<ctx_result_set_descriptor>
<group sdata="rating" bucketby="custom">
<range start="1" lessthan="10"/>
<range start="10" lessthan="20"/>
<range start="20"/>
</group>
<group sdata="price" bucketby="custom">
<range end="1"/>
<range greaterthan="1" end="10"/>
<range greaterthan="10" end="100"/>
<range greaterthan="100"/>
</group>
<group sdata="vendor" bucketby="custom">
<range greaterthan="a"/>
<range start="s"/>
<range end="f"/>
</group>
</ctx_result_set_descriptor>',
rs);
select xmlserialize(Document XMLType(rs) as clob indent size=2) into :displayrs from dual;
dbms_lob.freetemporary(rs);
end;
/
select :displayrs from dual;
The following is output:
<ctx_result_set>
<groups sdata="RATING">
<group value="range" start="1" lessthan="10">
<count>5</count>
</group>
<group value="range" start="10" lessthan="20">
<count>0</count>
</group>
<group value="range" start="20" end="5">
<count>0</count>
</group>
</groups>
<groups sdata="PRICE">
<group value="range" start="49" end="1">
<count>0</count>
</group>
<group value="range" greaterthan="1" end="10">
<count>0</count>
</group>
<group value="range" greaterthan="10" end="100">
<count>2</count>
</group>
<group value="range" greaterthan="100" end="129">
<count>3</count>
</group>
</groups>
<groups sdata="VENDOR">
<group value="range" greaterthan="a" end="second vendor">
<count>5</count>
</group>
<group value="range" start="s" end="second vendor">
<count>1</count>
</group>
<group value="range" start="fifth vendor" end="f">
<count>0</count>
</group>
</groups>
</ctx_result_set>
topn Attribute
-
Valid attribute values are non-negative numbers greater than zero.
-
This attribute specifies that only top
n
facet values and their counts are returned. -
Group count determines the top
n
values to return unless thesortby
attribute is set tovalue.
In that case, the values are sorted according to the data type and the topn
results of the sort are returned. The order attribute is respected for the sort. -
By default, the results are sorted by the group count in descending order.
-
If a tie occurs in the count, the ordering of the facet values within this tie is not guaranteed.
sortby and order Attributes
sortby
supports count
and value
attributes.
-
count
sorts by group counts (numbers). This is the default. -
value
sorts by value depending on the data type.
order
supports ASC
(ascending order) and DESC
(descending order), which is the default.
If there is no selection, the default is count DESC.
This example shows the grouping of a number facet if bucketby
is set to single,
where mytab_idx
is the name of the index, text
is the query, and group SDATA
requests the facets:
begin
ctx_query.result_set('mytab_idx', 'text',
'<ctx_result_set_descriptor>
<group sdata="sec01" topn = "4" sortby = "value" order="asc" bucketby="single">
<count/>
</group>
</ctx_result_set_descriptor>'
:rs);
end;
The following is a sample output showing that the values are listed in alphabetical order because the sortby
attribute is set to value
instead of count.
The values are also displayed in ascending order (ABC to XYZ) because the order
attribute is set to asc.
Only four values are displayed because the topn
attribute is set to 4.
<ctx_result_set>
<group SDATA="SEC01">
<group value="ABC"><count>2</count>
</group>
<group value="DEF"><count>1</count>
</group>
<group value="GHI"><count>10</count>
</group>
<group value="XYZ"><count>1</count>
</group>
</ctx_result_set>