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 and 2 with the name of an object you want to index.

  • FieldToIndex 1 through N 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 through N 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.

  • ChildFieldToIndex1 through N 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 which FieldToIndex field should be part of.

  • ConditionObjectFieldtoIndex1 through N 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.

For former Coveo Cloud V1 users, the Coveo Cloud V2 conditional indexing is the equivalent to the Manage Exclusion option from Coveo Cloud V1 (see Customizing the Salesforce Source Configuration).

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, and Excludes (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')
Recommended Articles