4

Can a SOSL query be used in the Batch apex start method?

I used the below code

global Database.QueryLocator start(Database.BatchableContext BC){
        return Database.getQueryLocator([FIND '.com' IN EMAIL FIELDS RETURNING Account (Id,Email__c),B__c(Id,Email_of_B__c)]);
    }

received the below error

Method does not exist or incorrect signature: Database.getQueryLocator(LIST>)

Could you please help me out. I need to mask the emails ids in those objects and hence have gone for batch. There are more objects to be included.

2 Answers 2

4

Yes, you should be able to do this, SOSL does return a List (which does implement the Iterable Interface). There may be other ways to do it as well, but you can redefine your Batch Apex start method to return an Iterable<Object> instead of a QueryLocator.

public class TestSOSLBatch implements Database.Batchable<Object> {

    public Iterable<Object> start(Database.BatchableContext bc) {
        return (Iterable<Object>)[FIND '.com' IN EMAIL FIELDS RETURNING Account (Id,Email__c),B__c(Id,Email_of_B__c)];
    }

    public void execute(Database.BatchableContext bc, List<Object> scope) {
        System.debug(JSON.serializePretty(scope));
    }

    public void finish(Database.BatchableContext bc) {

    }
}

The Batchable Interface is documented here where it specifies that the start method should return a System.Iterable object (which the results of a SOSL query is) or a Database.QueryLocator (which the results of a SOSL query is not).

I have tested this code in a DE org and it gives the expected results.

2
  • Thanks @Phil. I tried out your answer and it worked! Also as Keith suggested, it will not work for large number of records because of the limits. As i have nearly 6 objects to implement the same logic, i am planning on using a single generic batchable which can be called for all the 6 objects separately one after the other. Please suggest if there are better solutions Commented Oct 15, 2014 at 8:56
  • Sounds reasonable, why don't you inject your SOQL query string in the constructor and then daisy-chain your batch jobs together? You should accept my answer to the question you asked (@KeithC is absolutely right about limits, but my answer does answer your question correctly) and then ask another question IMO. Commented Oct 15, 2014 at 8:59
2

A major advantage of the Batchable approach is that providing a (SOQL) based Database.QueryLocator is returned from the start method, the Batchable can process up to 50 million records.

The governor limit on SOSL appears to be 2,000 records.

So while a SOSL-based Batchable may work (nice answer Phil Hawthorn), it is only of use for small numbers of objects. For the query in the question, I suggest instead creating two Batchables, one for Account and one for B__c, both using SOQL (with Email like '%.com') and Database.QueryLocator. Then when the number of matching rows exceeds 2,000 the code will still work.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .