JSON Salesforce Objects Section
JSON Salesforce Objects Section
In the JSON of a Salesforce source, you can access the Objects section (see Show Only One Configuration Section). This section presents all the Salesforce objects and fields to be indexed. It’s one of the main sections affected, along with the Mappings section, when you customize the Salesforce source from the Coveo Administration Console (see Advanced Configuration of a Salesforce Source).
However, you might want to customize your source configuration further than what the Edit panel allows. Most of the time, this is done to index fields from parent or child objects without indexing the parent or child item. It can also be used to introduce polymorphic or conditional indexing, so that the indexed fields or items are dependent on certain fields.
This article explains the structure of the JSON Salesforce source Objects section, so you can edit it better.
Basic Structure
The Objects section presents all the elements from the ObjectsToGet
section. The most important part is the Query
element, as it lists all the objects and fields to be returned when indexing the objects.
The following template is an example of the Objects section:
{
"sensitive": false,
"extendedData": {
"Query": [
{
"ObjectName": "NameOfYourObject1",
"Fields": {
"string": [
"FieldToIndex1",
"FieldToIndex2",
"FieldToIndexN"
]
}
},
{
"ObjectName": "NameOfYourObject2",
"Fields": {
"string": [
"FieldToIndex1",
"FieldToIndex2",
"FieldToIndexN"
]
}
}
]
}
}
In this template, you must replace the following values with your desired ones:
-
NameOfYourObject
1
and2
with the name of an object you want to index. -
FieldToIndex
1
throughN
with all the object fields you want to index.
When manually adding Objects and Fields to index in the JSON, you must remember to add field mappings to your objects (see Manage Source Mappings).
Introducing Parent Relationships
Parent relationships let you index fields from a parent object without having to index the object itself.
The following template is an example of a parent relationship:
"Query": [
{
"ObjectName": "NameOfYourObject",
"Fields": {
"string": [
"FieldToIndex"
]
},
"ParentRelationships": {
"ParentRelationship": [
{
"RelationshipName": "ParentObject",
"Fields": {
"string": [
"ParentObjectFieldToIndex1",
"ParentObjectFieldToIndex2",
"ParentObjectFieldToIndexN"
]
}
}
]
}
}
]
In this template, you must replace the following values with your desired ones:
-
NameOfYourObject
with the name of an object you want to index. -
FieldToIndex
with the object fields you want to index. -
ParentObject
with the parent object from which you want to index fields. -
ParentObjectFieldToIndex
1
throughN
with all the parent object fields you want to index.
You want to index your cases, but not your accounts. However, you still want to have the account name in the case fields.
In the JSON, in the Query
element, you enter the following:
"Query": [
{
"ObjectName": "Case",
"Fields": {
"string": [
"CaseNumber",
"Description",
"Subject"
]
},
"ParentRelationships": {
"ParentRelationship": [
{
"RelationshipName": "Account",
"Fields": {
"string": [
"Name"
]
}
}
]
}
}
]
Remember to add a %[Account.Name]
mapping to your object (see Manage Source Mappings).
Inside the query of your parent relationship, you can add parent relationships, polymorphic relationships, or conditional indexing (see Add Conditional Indexing for a Salesforce Source).
You need to add it after the Fields declaration, as such:
"Query": [
{
"ObjectName": "NameOfYourObject",
"Fields": {
"string": [
"FieldToIndex"
]
},
"ParentRelationships": {
"ParentRelationship": [
{
"ObjectName": "NameOfYourObject",
"Fields": {
"string": [
"FieldToIndex"
]
},
"ParentRelationships": ...
}
]
}
}
]
Introducing Child Relationships
Child relationships, like parent relationships, let you index fields from a child object without indexing the child itself.
The following template is an example of a child relationship:
"Query": [
{
"ObjectName": "NameOfYourObject",
"Fields": {
"string": [
"FieldToIndex"
]
},
"ChildRelationships": {
"ChildRelationship": [
{
"RelationshipName": "ChildObject",
"Fields": {
"string": [
"ChildFieldToIndex1",
"ChildFieldToIndex2",
"ChildFieldToIndexN"
]
}
}
]
}
}
]
In this template, you must replace the following values with your desired ones:
-
NameOfYourObject
with the name of an object you want to index. -
FieldToIndex
with the object fields you want to index. -
ChildObject
with the child object from which you want to index fields. -
ChildFieldToIndex
1
throughN
with all the child object fields you want to index.
You want to index your cases, but not your case comments. You however want the body of the case comment indexed as a field part of your cases.
In the JSON, in the Query
element, you enter the following:
"Query": [
{
"ObjectName": "Case",
"Fields": {
"string": [
"CaseNumber",
"Description",
"Subject"
]
},
"ChildRelationships": {
"ChildRelationship": [
{
"RelationshipName": "CaseComments",
"Fields": {
"string": [
"CommentBody"
]
}
}
]
}
}
]
Remember to add a %[casecomments.commentbody]
mapping to your object (see Manage Source Mappings).
Inside the query of your child relationship, you can add parent relationships, polymorphic relationships, or conditional indexing (see Add Conditional Indexing for a Salesforce Source).
You need to add it after the Fields declaration, as such:
"Query": [
{
"ObjectName": "NameOfYourObject",
"Fields": {
"string": [
"FieldToIndex"
]
},
"ChildRelationships": {
"ChildRelationship": [
{
"ObjectName": "CaseComments",
"Fields": {
"string": [
"CommentBody"
]
},
"ParentRelationships": ...
}
]
}
}
]
Creating Records From Children Fields
The CreateRecord
option lets you create an item from the children fields you index. As a Boolean option, it can either be set to true
or false
. Its default value is false
.
The following template is an example of how to use the CreateRecord
option:
"Query": [
{
"ObjectName": "NameOfYourObject",
"Fields": {
"string": [
"FieldToIndex"
]
},
"ChildRelationships": {
"ChildRelationship": [
{
"RelationshipName": "ChildObject",
"Fields": {
"string": [
"ChildFieldToIndex1",
"ChildFieldToIndex2",
"ChildFieldToIndexN"
]
},
"CreateRecord": true
}
]
}
}
]
Introducing Polymorphic Relationships
Polymorphic relationships let you index different fields depending on which object is returned (see Understanding Polymorphic Keys and Relationships).
The following template is an example of a polymorphic relationship:
"Query": [
{
"ObjectName": "NameOfYourObject",
"Fields": {
"string": [
"FieldToIndex"
]
},
"PolymorphicRelationships": {
"PolymorphicRelationship": [
{
"RelationshipName": "FieldToCheck",
"ObjectName": "ConditionObject",
"Fields": {
"string": [
"ConditionObjectFieldtoIndex1",
"ConditionObjectFieldtoIndex2",
"ConditionObjectFieldtoIndexN"
]
}
},
{
"RelationshipName": "FieldToCheck",
"ObjectName": "ConditionObject",
"Fields": {
"string": [
"ConditionObjectFieldtoIndex1",
"ConditionObjectFieldtoIndex2",
"ConditionObjectFieldtoIndexN"
]
}
}
]
}
}
]
In this template, you must replace the following values with your desired ones:
-
NameOfYourObject
with the name of an object you want to index. -
FieldToIndex
with the object fields you want to index. -
FieldToCheck
with the field whose object needs to be checked. -
ConditionObject
with the object whichFieldToIndex
field should be part of. -
ConditionObjectFieldtoIndex
1
throughN
with all the fields you want to index from the condition object.
When indexing your events, you want to index different fields depending on whether the what
field is an Account
or an Opportunity
.
When the Event
is related to an Account
, you want to index its NumberOfEmployees
field, and when the event is an Opportunity
, you want to index its Amount
field.
In the JSON, in the Query
element, you enter the following:
"Query": [
{
"ObjectName": "Event",
"Fields": {
"string": [
"Subject"
]
},
"PolymorphicRelationships": {
"PolymorphicRelationship": [
{
"RelationshipName": "What",
"ObjectName": "Account",
"Fields": {
"string": [
"NumberOfEmployees"
]
}
},
{
"RelationshipName": "What",
"ObjectName": "Opportunity",
"Fields": {
"string": [
"Amount"
]
}
}
]
}
}
]
Remember to add a %[what_account.numberofemployees]
and a %[what_opportunity.amount]
mapping to your object (see Manage Source Mappings).
You can add parent or child relationships in your polymorphic relationships, by using the following syntax:
"Query": [
{
"ObjectName": "NameOfYourObject",
"Fields": {
"string": [
"FieldToIndex"
]
},
"PolymorphicRelationships": {
"PolymorphicRelationship": [
{
"RelationshipName": "FieldToCheck",
"ObjectName": "ConditionObject",
"Fields": {
"string": [
"ConditionObjectFieldtoIndex1",
"ConditionObjectFieldtoIndex2",
"ConditionObjectFieldtoIndexN"
]
},
"ParentRelationships": {
"ParentRelationship": [
{
"RelationshipName": "ParentObject",
"Fields": {
"string": [
"ParentObjectFieldToIndex"
]
}
}
]
}
},
{
"RelationshipName": "FieldToCheck",
"ObjectName": "ConditionObject",
"Fields": {
"string": [
"ConditionObjectFieldtoIndex1",
"ConditionObjectFieldtoIndex2",
"ConditionObjectFieldtoIndexN"
]
}
}
]
}
}
]
Introducing Conditional Indexing
You can add conditional indexing directly from the Salesforce source configuration (see Managing Conditions Applied to an Object).
To prevent potential issues and source configuration errors, you’re encourage to use the source configuration instead of editing the JSON.
The Salesforce source lets you index items only when they meet specific conditions, which can reduce the size of your index.
To do so, you must enter the condition in the source JSON in the ObjectsToGet
element. It must be included as part of the object you want to index conditionally, after its field declaration.
There are two ways to add conditional indexing for a Salesforce source:
-
QueryCondition: Lets you change the operator used in the created SOQL query.
-
InConditionValue: Lets you list the allowed values in the created SOQL query.
QueryCondition
The QueryCondition element lets you index items that answer to a specific query.
The conditions must respect the following template:
"Query": [
{
"ObjectName": "Object",
"Fields": {
"string": [
"ObjectField"
]
},
"Conditions": {
"queryConditionOrQueryCondition2OrInCondition": [
{
"QueryCondition": {
"Field": "FieldToCheck",
"Operator": "OperatorToUse",
"Value": "ValueToMatch"
}
}
]
}
}
]
In this template, you must replace the following values with your desired ones:
-
Object and ObjectField: The Salesforce object and its fields to index.
-
FieldToCheck: The Salesforce field the source should check for the matching value. The field must be one of the fields specified in your object, or the source will fail to build.
-
OperatorToUse: The operator you want to use when comparing your field to its value. The accepted values are
=
,!=
,>
,<
,<=
,>=
,Like
,NotLike
,Includes
, andExcludes
(see SOQL Operators). -
ValueToMatch: The value the field must have to be indexed.
String values must be between double and single quotes (e.g.,
"'Phone'"
).Boolean and Date values must be in double quotes (e.g.,
"true"
,"2017-06-01T00:00:00.0000000-00:00"
).
It results in the following query:
SELECT ObjectField FROM Object WHERE FieldToCheck OperatorToUse ValueToMatch
You can decide to add several QueryCondition
one after the other, inside the queryConditionOrQueryCondition2OrInCondition
element. The resulting SOQL query simply adds AND
to every condition.
For your Salesforce source, you want to index Cases only when their Origin field isn’t Phone.
In the JSON of the source, as part of the ObjectsToGet
element, you have the following elements:
"Query": [
{
"ObjectName": "Case",
"Fields": {
"string": [
"Origin"
]
},
"Conditions": {
"queryConditionOrQueryCondition2OrInCondition": [
{
"QueryCondition": {
"Field": "Origin",
"Operator": "!=",
"Value": "'Phone'"
}
}
]
}
}
]
This results in the following query:
SELECT Origin FROM Case WHERE Origin != 'Phone'
InCondition
The InCondition element lets you index items only when one of their field has a specific value from your listed values.
The condition must respect the following template:
"Query": [
{
"ObjectName": "Object",
"Fields": {
"string": [
"ObjectField"
]
},
"Conditions": {
"queryConditionOrQueryCondition2OrInCondition": [
{
"InCondition": {
"Field": "FieldToCheck",
"InConditionValue": {
"name": "AllowedValues",
"declaredType": "com.coveo.cloud.source.model.sourceconfig.salesforce.generator.AllowedValues",
"scope": "javax.xml.bind.JAXBElement$GlobalScope",
"value": {
"ConditionValue": [
{
"name": "FieldType",
"declaredType": "java.lang.String",
"scope": "javax.xml.bind.JAXBElement$GlobalScope",
"value": "ValueToMatch",
"nil": false
}
]
},
"nil": false
}
}
}
]
}
}
]
In this template, you must replace the following values with your desired ones:
-
Object and ObjectField: The Salesforce object and its fields to index.
-
FieldToCheck: The Salesforce field the source should check for the matching value. The field must be one of the fields specified in your object, or the source will fail to build.
-
FieldType: The type of the field to check. The accepted values are:
-
SoqlString
: a string. -
SoqlBoolean
: a Boolean value. -
SoqlDateTime
: a date. The format must respect the SOQL date format (see Date Formats and Date Literals).
-
-
ValueToMatch: The value the field must have to be indexed. Ensure that the value is still in quotes, even for Boolean values.
It results in the following query:
SELECT ObjectField FROM Object WHERE FieldType IN ('ValueToMatch')
For your Salesforce source, you want to index Cases only when their Status field is either Escalated or Closed.
In the JSON of the source, as part of the ObjectsToGet
element, you have the following elements:
"Query": [
{
"ObjectName": "Case",
"Fields": {
"string": [
"Status"
]
},
"Conditions": {
"queryConditionOrQueryCondition2OrInCondition": [
{
"InCondition": {
"Field": "Status",
"InConditionValue": {
"name": "AllowedValues",
"declaredType": "com.coveo.cloud.source.model.sourceconfig.salesforce.generator.AllowedValues",
"scope": "javax.xml.bind.JAXBElement$GlobalScope",
"value": {
"ConditionValue": [
{
"name": "SoqlString",
"declaredType": "java.lang.String",
"scope": "javax.xml.bind.JAXBElement$GlobalScope",
"value": "Escalated",
"nil": false
},
{
"name": "SoqlString",
"declaredType": "java.lang.String",
"scope": "javax.xml.bind.JAXBElement$GlobalScope",
"value": "Closed",
"nil": false
}
]
},
"nil": false
}
}
}
]
}
}
]
This results in the following query:
SELECT Status FROM Case WHERE Status IN ('Escalated', 'Closed')