SwiftlySalesforce icon indicating copy to clipboard operation
SwiftlySalesforce copied to clipboard

Enhance SOSL to support AnyPublisher<QueryResult<T>

Open perbrondum opened this issue 5 years ago • 6 comments

Is there any reason SOSL can not support AnyPublisher<QueryResult<T>?

perbrondum avatar Sep 11 '20 22:09 perbrondum

@perbrondum the Salesforce REST API search resource returns an array of records, and those records could be of different types depending on the domain of the SOSL search. In contrast, QueryResult for a SOQL search includes records of only 1 type, and includes metadata about the search results.

What is your requirement? What are you trying to achieve?

mike4aday avatar Sep 14 '20 16:09 mike4aday

Finding an efficient fast way to find all object records (or nil) belonging to a company.

FIND {tap2sales} In name FIELDS RETURNING Account(id, name), opportunity(id, name), contact(id, name, accountId)

Basically if I could get the above (simplified) query to work, and separate the records by type, I'd be happy. How would you refer to the "contact ID" in the above sosl?. Using id.prefix(4) == 0061 to identify an Opportunity post query does not seem ideal but it may be the only way.

I have it working in SOQL (multiple queries) but the power of SOSL when looking for a name across types is simpler and I'd like to use it.

Per

On Mon, Sep 14, 2020 at 6:42 PM Michael Epstein [email protected] wrote:

@perbrondum https://github.com/perbrondum the Salesforce REST API search resource returns an array of records, and those records could be of different types depending on the domain of the SOSL search. In contrast, QueryResult for a SOQL search includes records of only 1 type, and includes metadata about the search results.

What is your requirement? What are you trying to achieve?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/mike4aday/SwiftlySalesforce/issues/123#issuecomment-692176423, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALCYWDAHZTD2NCVVF3AWNFTSFZBY3ANCNFSM4RIN3XWA .

perbrondum avatar Sep 14 '20 23:09 perbrondum

@perbrondum do all the objects you're looking for have a lookup relationship to Account (e.g. Opportunity and Contact)? If so, you could use a parent-to-child SOQL query.

I don't understand your second paragraph about ID prefixes and referring to Contact ID - would you clarify? (Also: only the first 3 characters of the record ID could be used to discern the object type -- see this help article.)

mike4aday avatar Sep 15 '20 17:09 mike4aday

Using parent-child gets complicated with outer joins especially as we want to expose null records.

Below's an example of what I meant with contact Id. let sosl = "FIND {%(searchStr)%} IN name FIELDS RETURNING Account(id, name), opportunity(id, name), contact(id, name, accountId) DB.salesforce.search(sosl: sosl).sink(receiveCompletion: { (completion) in switch completion { case .finished: break case let .failure(error) : print(error) } }) { (searchResults: [SObject]) in let name = searchResults.string(forField: "Name")! ... How do I refer to a specific 'name' (contact or account) in the above line?

perbrondum avatar Sep 15 '20 19:09 perbrondum

Hi @perbrondum the results will be returned in an array of Records. The object property of each Record will tell you its type (e.g. "Contact") and then you could call record.value(forField: "Name").

mike4aday avatar Sep 17 '20 21:09 mike4aday

Beautiful. This is just awesome. Thanks.

let sosl = "FIND {%(textField.text!)%} IN Name FIELDS RETURNING Account(id, Name, BillingStreet, BillingCity, BillingPostalCode, BillingState, BillingCountry, lastActivityDate), Contact(id, name, MailingStreet, MailingCity, MailingPostalCode, MailingState, MailingCountry), Opportunity(id, name, expectedRevenue)"

        DB.salesforce.search(sosl: sosl)
            .sink(receiveCompletion: { (completion) in
                switch completion {
                case .finished:
                    print("Success SOSL query")
                case let .failure(error) :
                    print(error.localizedDescription)
                }
            }) { [self] (searchResults: [SObject]) in
                for row in searchResults {
                    switch row.object {
                    case objects.Account.rawValue:
                        existingAccounts.append(row)
                    case objects.Contact.rawValue:
                        existingContacts.append(row)
                    case objects.Opportunity.rawValue:
                        existingOpportunities.append(row)
                    default:
                        break
                    }
                }
                DispatchQueue.main.async {
                    accTable.reloadData()
                    ...
                }
            }.store(in: &self.subscriptions)

perbrondum avatar Sep 19 '20 17:09 perbrondum