Adaptive Search Queries

Managing Query Definitions

There is no mandatory standard for the query definitions resource URL, but we will follow the recommendations. We will use the following URL to manage queries for GET methods: <root>/custom-actions/queries/<entity-name>, whereas we will use <root>/custom-actions/queries/ for POST methods.

As mandated, we will use the Prefer Header to determine whether the query should be saved or not.

The changes made to hierarchies are not immediately visible in Adaptive Search results. They are visible only after the Adaptive Search’s periodic refresh or after a full publish of the hierarchy owner or resource.

To do a full publish of the hierarchy owner or resource:
  1. Navigate to the Configure Adaptive Search task.
  2. Click Setup > Advance > Account.

  3. Select the hierarchy owner or resource, and then select any attribute.
  4. Click Publish.

    This will refresh the hierarchy and you will see the hierarchy changes in the Adaptive Search results.

Use of Preference Header

Transient query results are not saved on the server and thus cannot include a 'self' or 'next' link. If the 'return=query-result' is specified while creating or updating a query, then the query definition is created and the result is returned immediately.

201 Created
Location: http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries/<uuid>
...
{
  "q":  <query expression>,
  "links": [
  {"rel": "self", "href": "http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries/<uuid>"},
   {"rel": "http://xmlns.oracle.com/rest/queried-collection", "href": "http://example.com/api/v1entities/<pattern>"},
   {"rel": "search", "href": "http://example.com/api/v1/custom-actions/queries/<pattern>"},
   {"rel": "http://xmlns.oracle.com/rest/latest-result", "href": "http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries/<uuid>/results"}
 ]
}

HTTP Requests

You can use HTTP requests such as get, delete, post, and patch to manage query definitions.

Create Query

If the client uses POST, then the server will generate the URI. Use of PUT requires the client to specify the <uuid> that identifies the query. If the query was previously defined, then the new query replaces it. Since we cannot guarantee that the client generates a new uuid, and also whether the uuid is unique, we return 400 Bad Request for PUT requests that create a query.

Get Query

Each query definition resource is a standard, singular resource. The client may issue a GET request to retrieve the query definition:

GET http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries/<uuid>

Get Query Results

To get the latest query result, use GET request, such as:

GET http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries/<uuid>/results
The query results URL supports the following additional URL parameters apart from the normal parameters that are required by all collections:
  • totalResults=true - provides an estimated result count
  • sort - the parameter value is a comma separated string of fields paths to sort by, each optionally followed by a column and "asc" or "desc". If this parameter is specified, it overrides and sorts specification in the query expression itself. If "orderBy" is given without any parameter value, then the sort is by relevancy.

Retrieving Queries

All the queries that the user has access to, and that are not hidden, can be retrieved using the following request:

GET http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries

The default query for the user can be retrieved using the following request:

GET http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries?default

All the queries for a specific top-level entity that a user has access to, and that are not hidden, can be retrieved using the following request:

GET http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries?entity=Account

All the global queries, such as queries that cut across entities, can be retrieved using "_global" using the following request:

GET http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries/?entity=_global

All the queries for a set of top-level entities that a user has access to, and that are not hidden, can be retrieved using a comma delimited list with the following request:

GET http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries?entity=Account,Contact

Note that <entityName> can be a top-level entity name or "_global".

Update Query

Changing the query definition is done through PATCH request and the request will fail with,
  • a 403 HTTP error code if the query is private and the user did not create the query, or if the query is not private and the user is not the administrator.
  • a 404 HTTP error code if the query no longer exists.

Delete Query

The client may decide to remove the query definition with a DELETE request and the request will fail with,
  • a 403 HTTP error code if the query is private and the user did not create the query, or if the query is not private and the user is not the administrator.
  • a 404 HTTP error code if the query no longer exists.

Query Definition

A query is a JSON object with the following properties:
  • queryUuid - the primary key of a saved query definition
  • default - a boolean that indicates whether or not the query is the default for the user
  • accessLevel - Indicates the level of access, such as "Private", "Public", "Role", or "Hidden"
  • roles - the list of roles that are associated with a saved search
  • updateable - a boolean that indicates whether or not the query can be updated by the user
  • _entity - the name of the entity that the definition is for
  • name - the localized name for a saved query based on the user's language as obtained from User Preferences
  • description - the localized description for a saved query based on the user's language as obtained from User Preferences
  • user - the party id of the resource that created the query definition
  • keywords - a string that represents the keywords to search for, if any
  • keywordsFields - a JSON array of fields in which the keywords are searched for, which defaults to "."
  • fields -
  • excludeFields -
  • q - the query specification
  • sort - an array of sort fields or null to sort based on relevancy
  • applications - the subset of the applications associated with the query that are included in the applications query parameter, which is a comma delimited list
  • applicationData - the data that is associated with the query for each of the applications

Associating Queries With Applications

It is possible that a query can be defined in one application and used in a different application. For example, if you define a query defined in the FUSE UI and use it in the Mobile application, then the query results may be rendered differently. However, the basic query such as "My Open Opportunities in Pittsburgh, PA" remains the same.

In the FUSE UI, that query may be rendered with filters that enable exploration, but in Mobile that query may be rendered differently. Some applications may want to only retrieve queries for "their" application, while others may want to retrieve all queries that the user has access to.

A user can retrieve multiple applications' saved searches by supplying a list of applications to this parameter. The payload would return the saved search definition along with the application data.

All the queries that the user has access to that are not hidden for a particular application with uuid 1ad55460-b782-11e8-b568-0800200c9a66 can be retrieved using the following request:

GET http://servername.fa.us2.oraclecloud.com/crmRestApi/searchResources/11.13.18.05/custom-actions/queries?applications=1ad55460-b782-11e8-b568-0800200c9a66

Query Expression

Each "attribute" in the query expression is either a bind parameter or a field, designated by a document attribute path. See Adaptive Search REST: Query Expression for the detailed syntax.

Sort Field

Each sort field is a JSON object with the following properties that follow the JET CCA standard:
  • attribute - the document field path to an attribute
  • direction - either "ascending" or "descending"
example :

"sort": [
        {
            "attribute": "PartyUniqueName",
            "direction": "ascending"
        }
    ]

Copied From

The copied from property specifies the URL for the resource that provides the initial query definition. Any property that is specified in the request payload will override what is defined in the saved query definition. Furthermore, the reference to the saved query definition is removed when a new query is created or updated, by copying the non-override pieces.

"copiedFrom": "<the URL for a saved query definition>"

Note that if copiedFrom is provided, then the entity property need not be provided. If the entity property is provided, then it must be the same as the entity of the copiedFrom.

Fields and Exclude Fields

In order to limit the payload to the aforementioned fields, we use "fields" and "excludeFields" for filtering, which correspond to the "includes" and "excludes" directives in Adaptive Search Source filtering. These are arrays of fields paths and wildcards (*) are supported in the directives. The "_actions" field is a special field that is there just to provide layout information for actions. Language-specific fields for languages other than the user's language are automatically omitted. For example, if a user's language is "US", then all non-US language fields are automatically omitted. To omit all language fields, simple include the following pattern in the excluded fields: "*_*".

If a localized field is included in the fields parameter then the corresponding localized field for the user's language is also includes. For example, if the user requests that "PrimayAddress.CountryCode" is to be included in the payload, then "PrimaryAddress.CountryCode_localizedValue" is also included in the payload, unless the excludeFields pattern omits it.

Exclude Fields takes precedence over Fields.

<fields> ::=='['<field>[, <field>]*']<field>::== a string that represents a field or is a wild card expression using '*'<excludeFields> ::== '['<field> [, <field>]*']

Exclude Links

The "excludeLinks" property is a list of the links, by relation name, that should be excluded from the payload

Exclude Properties

The "excludeProperties" property is a list of properties that should be excluded from the payload. For example, to eliminate aggregations in cases where filter panel is not shown, specifying "excludeProperties": ["aggregations"] will exclude aggregations from the payload

Applications

As a query parameter to GET, the applications parameter specifies the list of applications that the queries should be returned for and the response will include only queries that are tied to one of the specified applications. The applications property in the response will be a list of the applications that the query applies to (and this will be a non-null subset of the comma delimited list specified in the query parameters. In addition the payload will include the application data for each application, if it exists and the links in the response will also replicate the applications query parameter.

If the applications query parameter is not specified. then the query (or queries) are retrieved irrespective of the application and the response will not populate the applications property. On the other hand, if the applications are specified in the query parameter or payload, then the response will include those same values.

Application Data

To bridge the gap until all the applications have moved to JET/VBCS, this REST service will support storing a CLOB column of application data. The application data , which can be excluded from the payload, provides a JSON map of application specific data. Application data will only be returned for the applications that were specified in the applications query parameter, according to the following BNF:

<application data> ::== null | \{ "<application uuid>": "<application specific data>" [,"<application uuid>": "<application specific data>"] \}<application specific data> is a string

When updating, the REST service will only update the entries that are provided in the payload and leave any other application data. To remove data for an application, the map for the application data should simply include a entry with a null value, e.g. the following fragment will remove the application specific data for the application with uuid: 1ad55460-b782-11e8-b568-0800200c9a66

"applicationData": \{"1ad55460-b782-11e8-b568-0800200c9a66": null \}

There are situations when an application may want to retrieve all the queries that the user has access to irrespective of the application and also retrieve the application data for one or more applications, if available. This is accomplished by specifying the a comma delimited list of applications to retrieve in the application data query parameter.

Aggregations

Aggregations used to get the counts for the "facets" in the UI or for building charts. A query request can also include the request to build aggregations, whose structure is given by the following:

<aggregations> ::== \{ <aggregation> [, <aggregation>]* \}<aggregation> ::== <filters aggregation> | <terms aggregation> | <metric aggregation>

If the client is not interested in the query results, then specifying limit=0 as a query parameter or payload will not return any query results.

To support faceted search, each aggregation can specify a single attribute to ignore. If the query expression that defines the result set includes a criterion that refers to an "ignored" attribute, then the underlying call will leverage the "filter" and "post_filter" capability in Adaptive Search's REST API as follows provided aggregations are not ignored:
  • The query expression must leverage either a single criterion or a top-level logical AND
  • If query results are needed, then the query criteria will be split into two query expressions:
    • every conjunct that includes a reference to an ignored attribute, recursively, will be placed into the "post filter" query expression, see (see Post Filter).
    • every conjunct that does not include a reference to an ignored attributes, recursively, will be places into the "base" query expression.
  • A filter will be added to each aggregation to include the pieces of the "post filter" query expression that do not reference the "ignored" attribute, if any

Range Aggregations

Range Aggregation specify ranges to build aggregations for and encapsulate both range and date range aggregation in Adaptive Search depending on the attribute type, as defined by the following BNF:

<range aggregation> ::== "<aggregation name>" : \{ "range": \{ "attribute": <field>, "ignore": <boolean>, "ranges": \[ <range> [, <range>] \] \} \}<aggregation name> ::== alpha numeric string that cannot contain "_" and uniquely identifies the aggregation within the set of aggregations<field> :== the document attribute path for a field<range> ::== \{"key": <key>, "to": <value> \} | \{"key": <key>, from": <value>, "to": <value> \} | \{"key": <key>, "from": <value> \"},<key> ::== the key for the bucket to be returned in the aggregation result<value> :: == value constituting the attribute type for the field. If the field is a date. time, or timestamp, then the value must be a string in "yyyy-MM-dd". "HH:mm:ss.SSS", or "yyyy-MM-dd'T'HH:mm:ss.SSSZ" format or be an Adaptive Search Date Math Expression.

The following code shows an example of a range aggregation.

{ 
   "PrimaryRevenue.WinProb":{ 
      "range":{ 
         "attribute":"PrimaryRevenue.WinProb",
         "ignore":true,
         "ranges":[ 
            { 
               "key":"0...20",
               "from":0,
               "to":20
            },
            { 
               "key":"20...40",
               "from":20,
               "to":40
            },
            { 
               "key":"40...60",
               "from":60,
               "to":80
            },
            { 
               "key":">= 80",
               "from":80
            }
         ]
      }
   }
}

Although we use the document attribute path for the aggregation name, in this example, the name of the aggregation can be anything, provided it is a valid JSON property name and that it is unique within the set of aggregations. The result will return a set of buckets that correspond to the specified ranges in the same order as the request, as defined in the following BNF:

<range aggregation result> ::== "<aggregation name>": \{ "buckets": \{ <bucket result> , <bucket result>]+ \}<aggregation name> ::== alpha numeric string that cannot contain "_" and uniquely identifies the aggregation within the set of aggregations<bucket result> ::== "<key>": \{ "count": <bucket count> \}<bucket count> ::== the number of documents for the specified key

The following fragment defines a possible response to the preceding filters aggregation.

{ 
   "PrimaryRevenue.WinProb":{ 
      "buckets":{ 
         "0...20":{ 
            "count":10
         },
         "20...40":{ 
            "count":140
         },
         "40...60":{ 
            "count":56
         },
         "60...80":{ 
            "count":45
         },
         ">= 80":{ 
            "count":90
         }
      }
   }
}

Terms Aggregations

Terms aggregations specify an attribute for which the top-most frequent buckets are dynamically built, one per unique value. It also provides the capability of computing the missing aggregation. The maximum number of buckets to be returned is specified with the "maxBuckets" parameters. If "other" is set to true, then, in addition to the top terms, a count is computed for the number of documents that do not match the top terms. If "missing" is set to true, a count of the number of documents whose value is missing is returned and the count for "other" will be the number of documents that do not match the top terms and that do not have a missing value. Finally, the "localize" property is used to indicate whether or not the keys should be localized if the keys are for an attribute that is a lookup type or for an entity. If the keys are for a lookup type, then the language of the user is used to localize the value. If the keys are for an attribute that is an foreign key, then the display attribute for the entity of the foreign key attribute will be used for localization.

A terms aggregation is specified according to the following BNF syntax:

<terms aggregation> ::== "<aggregation name>":\{ "ignore": <boolean>, "terms": {"attribute": <field>}, "minDocumentCount": <minimum document count>, "maxNumberOfBuckets": <maximum number of buckets> [, "other":true]? [, "missing":true]? [, "localize":true]?\}<ignore> ::== true if the attribute used in the terms should be ignored when building this aggregation and be enforced in post filter<field> ::== the document attribute path for the field to aggregate on<aggregation name> ::== alpha numeric string that cannot contain "_" and uniquely identifies the aggregation within the set of aggregations<minimum document count> is an integer >= 0 that defaults to 1 such that buckets whose counts fall below this value are ignored<maximum number of buckets> is an integer > 0

The response will include the key and the counts according to the following BNF syntax, where the counts are sorted in descending order.

<terms aggregations response> :: == "<aggregation name>": \{ "buckets": <array of key responses> [, "missing": <count>] [, "other": <count>] \}<array of key responses> ::== \[\] | \[ <key response> [, <key response>]+\]<key response> ::== \{ "key:" <attribute value>, "count": <count> [,"localizedKey": <localized key>]? \}<attribute value> ::== the value for an integer<count> is an integer >= 0 that has the count for the specified attribute value, missing value, or other value

Of course, in the degenerative case where there is no key with a specific value, then the buckets array will be empty.

The following JSON fragment defines a terms aggregation for the 5 most common sales stages while additionally computing the counts for missing document values and values that are not in the top 5 and not missing.

"SalesStageId": {
    "ignore": true,
    "terms" : {
        "attribute": "SalesStageId",
        "maxNumberOfBuckets" : 5,
        "other": true,
        "missing": true, 
        "localize": "true"
        "includeTerms":[100000012057019,100000012057020],
        "excludeTerms":[100000012057033]
    }
}

The response for the preceding terms aggregation might look as follows, assuming the language for the user is "US"

"SalesStageId":{ 
      "buckets":[ 
         { "key":100000012057019, "count":305, "localizedKey": "Negotiation"},
         { "key":100000012057020, "count":200, "localizedKey": "Close"},
         { "key":100000012057008, "count":100, "localizedKey": "Discovery"},
         { "key":100000012057017, "count":50,  "localizedKey": "Short List"},
         { "key":100000012057018, "count":2,   "localizedKey": "Closed"}
      ]
      "missing": 2,
      "other: 10
 }

Metric Aggregations

Metrics aggregations specify a set of filters with an optional bucket that counts the number of documents that do not match any of the specified filters, according to the following BNF syntax:

<metric aggrefation>::=="<aggregation name>":\{ "ignore": <boolean>, "metric": <metric> "attribute": "<field>"\}

Where:

  • <ignore> ::== true, if the attribute used in the terms should be ignored when building this aggregation and be enforced in post filter
  • <attribute> ::== the document attribute path for the field to aggregate on
  • <metric> can be one of the following:
    • avg - the average of numeric values value
    • cardinality - the approximate count of distinct values
    • max - the maximum value over numeric values
    • min - the minimum value over numeric values
    • stats - stats aggregation over numeric values
    • sum - the sum of numeric values
    • value_count - the number or values

The metric that returns a single value has the same response:

<metric aggregation result> ::== <aggregation result for metric that returns a single value> | <stats aggregation result>
<aggregation result for metric that returns a single value> :: == "<aggregation name>": \{ "value": <number>\}
<stats aggregation result> :: == "<aggregation name>": \{ "count": <number>, "min": <number>, "max": <number>, "avg": <number>, "sum": <number>\}

Highlighting

Adaptive Search supports the ability to get highlighted snippets from one or more fields in the search results so that users can see where the query matches are. Queries in Adaptive Search will highlight the fields leveraged in the query if the following is passed as part of the request.

"highlights" : {"pre": "\<em>", "post": "\</em\">, "fields": \[<field> [,<field> [, <field>]+\]\}

Each field that is specified as a field will have the indexed value and the highlighted value. For example, if we were searching for "Pinnacle" and the PartyUniqueName field is specified as one of the highlight fields we might see the following for an item in the result set.

{
    "PartyUniqueName": "Pinnacle Technologies",
    "PartyUniqueName_highlight": "<em>Pinnacle</em> Technologies"
}

Query Result

A query result is a collection, which isa special kind of resource that supports pagination. The JSON for a collection is as follows:
  • "items" - an array that contains the current "page" of resources
  • "count" - an integer that represents the number of items in the current fetch
  • "hasMore" - is a Boolean that indicates whether or not another page of results is possible
  • "offset" - the zero-based integer offset of the first item in this page of items in the collection
  • "limit" - the maximum number of items to return in a single request. The minimum value is 1 and the maximum and default values can be configured
  • "totalResults" - an integer that represents the number of items in the collection, where -1 indicates that the size is unknown
The query result items includes the following additional attributes,
  • timeInMilliseconds

Item

The most straightforward approach is to simply include the JSON document that has the raw values for the fields that the client is interested in for each item. For example, if the client specified that they were only interested in "PrimaryRevenue.WinProb", "Name", "CustomerAccount.PartyId", "PrimaryRevenue.RevnAmount", "EffectiveDate", "Owner.PartyId", and "SalesSategId", then the following would include all of the raw data that the client requested.

{
   "PrimaryRevenue.WinProb":10,
   "Name":"Pinnacle Technologies 112 Server Deal",
   "CustomerAccount":999997550268467,
   "PrimaryRevenue.RevnAmount":120000,
   "EffectiveDate":1278907200000,
   "Owner":100010032635399,
   "SalesStageId":100000012057020
}

Although this kind of payload might be adequate for bulk operations, it is not sufficient in cases where localization is required. Consider, for example, the use case were a UI is requesting a list of opportunities that it wishes to display in a table. The following payload would be more useful:

{ 
   "PrimaryRevenue.WinProb": "10%",
   "OpportunityName":"Pinnacle Technologies 112 Server Deal",
   "CustomerAccount":"Pinnacle Technologies",
   "PrimaryRevenue.RevnAmount":"120,000 USD",
   "EffectiveDate":"July 13, 2010",
   "Owner":"Dan Foreman",
   "SalesStageId":"Open"
}
The UI could simply render the strings in the table without any need to localize the raw values. Of course, the UI would need raw values for things like drill down. Rather than providing the fully localized information along with the raw values, it would be sufficient to provide the information that is needed by the UI to do its own localization. Let's take a look at what information is needed for localization based on the attribute type.
  • Nothing other than the raw value and user's preference and is needed by the client for localization of a boolean, a date, a percentage, a number, a string, a text, a time, or a timestamp
  • In addition to the raw value, the currency code is needed by the client for localization of a currency. Since the metamodel indicates the attribute that holds the currency code for a currency attribute, the client can simply request the currency code attributes that are needed as part of the payload and use them for localization.
  • A client needs the localized string that is associated with an enum value for localization. Adaptive Search stores the localized value for a enum attribute in an attribute whose name is the name of the attribute suffixed with "_" and with a language code. For example, the string in the "US" language for the attribute "SalesStageId" would be found in "SalesStageId_US". By requesting the language specific values, the client will have the necessary information to localize enumerations
  • To simplify client code, when an enum field is requested, then the REST API will automatically return the localized value unless it is excluded from the payload
  • Localization of a foreign key, such as Owner, requires the client to render the display attribute for the foreign key. Since the metamodel indicates what the display attribute is for an entity and since the display attribute for a foreign key is always part of the denormalization of a foreign key, the client simply needs to request the appropriate attribute in the payload
  • Localization of a record requires the use of the display attribute for the entity of the record. Since the metamodel indicates what the display attribute is for an entity, the client simply needs to request the appropriate attribute in the payload

Thus, the following would be sufficient for the client to localize the aforementioned attributes without any additional requests.

{ 
   "PrimaryRevenue.WinProb":10,
   "Name":"Pinnacle Technologies 112 Server Deal",
   "CustomerAccount.PartyId":999997550268467,
   "CustomerAccount.PartyUniqueName": "Pinnacle Technologies",
   "PrimaryRevenue.RevnAmount":120000,
   "PrimaryRevenue.RevnAmountCurcyCode": "USD",
   "EffectiveDate":1278907200000,
   "Owner.PartyId":100010032635399,
   "Owner.PartyName": "Dan Foreman",
   "SalesStageId":100000012057020,
   "SalesStageId_localizedValue":"Open"
}

The preceding approach, however, does not work very well when considering hierarchical content that embeds 1:many relationships, for example, the addresses for an organization. To remedy this situation, we will not flatten attributes, but rather retain the hierarchy, as shown by the following.

{ 
   "PrimaryRevenue":{ 
      "WinProb":10,
      "RevnAmount":12000,
      "RevnAmountCurcyCode":"USD"
   },
   "Name":"Pinnacle Technologies 112 Server Deal",
   "CustomerAccount":{ 
      "PartyId":999997550268467,
      "PartyUniqueName":"Pinnacle Technologies"
   },
   "EffectiveDate":1278907200000,
   "Owner":{ 
      "PartyId":100010032635399,
      "PartyName":"Dan Foreman"
   },
   "SalesStageId":100000012057020,
   "SalesStageId_US":"Open"
}

In order to limit the payload to the aforementioned fields, we use "fields" and "excludeFields" for filtering, which correspond to the "includes" and "excludes" directives in Adaptive Search Source filtering. Wildcards (*) are supported in the directives. For example the following "fields" directive would limit the source retrieved from Adaptive Search to include only what is needed:

"fields":[ 
   "PrimaryRevenue.WinProb",
   "PrimaryRevenue.RevnAmount",
   "PrimaryRevenue.RevnAmountCurcyCode",
   "Name",
   "CustomerAccount.PartyId",
   "CustomerAccount.PartyUniqueName",
   "EffectiveDate",
   "Owner.PartyId",
   "Owner.PartyName",
   "SalesStageId"
]

Links

The query results for a query should include the following links,
  • a "self:" link that refers to the URL for the query definition that was used to define the query results. If the query is a transient query, then the self link cannot be generated
  • a "http://xmlns.oracle.com/rest/queried-collection" link that refers to the entity that each item in the result set is for. If the query is for multiple entities, then this link cannot be generated
  • a "parent" link that refers to the URL for the query definition that was used to define the query results. If the query is a transient query, then the self link cannot be generated
  • a "search" link that defines the URL that was used to create the query
  • a "http://xmlns.oracle.com/rest/latest-result" link that defines the latest result.

Searching across more than one entity

There are occasions when it makes sense to search across entities and the Adaptive Search REST service needs to support such use cases. The following requirements must be considered,
  • There must be a way to specify that a "global" search applies to all searchable entities in order to handle entities that were introduced after the query was created, such as for a custom object.
  • There must be a way to specify that a "global" search applies to a specific subset of the searchable entities
  • There must be a way to default which fields are returned for an entity. By default the fields returned for a searchable entity should include
    • the field that stores the primary key
    • the field that stores the display key
    • the field that stores the owner
    • the fields that store the WHO columns
  • There must be a way to retrieve the fields for an entity that store the primary key, the display key, the owner, and the WHO columns in order to be able to interpret the results when the fields for an entity are not explicitly conveyed
  • There must be a way to specify which fields should be returned for an object being searched to support a list view since the information that should be shown in each entity card may be very different
  • There should not be a means of specifying the sort field as sorting across documents on anything other than relevance makes little sense unless all of the documents share the same field, which cannot be guaranteed without enforcing this condition on each top-level entity
  • There should be a means of highlighting the results
  • There should be a means of doing a keyword search

The keywords field would apply to the "all" field of each entity and the query expression for a search that cuts across searchable objects can only leverage the fields that are shared, i.e., "Owner", "LastUpdatedBy", "LastUpdateDate", "CreatedBy", and "CreationDate".

The "entities" property will be used to specify the entities to search and a null value indicates that the search is across all searchable objects, according to the following BNF syntax:

<entities> ::== \{ "<entity name>" : \{ "fields": \["<field>" [, <field>]* \], "excludeFields": \["<field>" [, <field>]*\] \}

If no entry is given in the "fields" or "excludeFields" property for an entity to be searched, then the default fields will be used, namely the primary key, the display key, the owner, and the WHO columns.

Highlighting is supported when the highlighting tag is provided, as follows:

"highlight" : \{"pre": "\<em\>", "post": "\</em"\>\}

The use of bind Variables and use of copied from are exactly the same as in any other query definition.

The use of "fields" and "excludeFields" as top-level properties is not allowed.

Each item in the response will always include the "_entity" field. If highlighting has been enabled, then the item will also include the "_highlights" field.