0

I've found quite a bit of literature on my error, but most of it is above my head, unfortunately. What I'm trying to do is run 2 queries, put them in lists, then run a third query with the list of returned values as parameters. (This is the most effecient way I can think of, so if there are other alternatives, please advise.)

Here is my code for queries:

List<TopicAssignment> ta = [SELECT EntityId FROM TopicAssignment WHERE TopicId = '0TO30000000Xea1GAC'];
System.Debug(ta);

List<CollaborationGroupFeed> cgf = [select ParentId from CollaborationGroupFeed WHERE ParentId = '0F936000000cWkMCAU'];
System.Debug(cgf);

List<FeedItem> chatFeed = [SELECT  Id, Body, CommentCount, CreatedDate, LikeCount, LinkUrl, ParentId, RelatedRecordId, Title, Type,
                                (SELECT Id, CommentBody, CreatedDate, CreatedById, FeedItemId, ParentId FROM FeedComments)
                            FROM FeedItem 
                            WHERE (Id IN :ta
                            OR ParentId in :cgf)
                            AND CreatedDate >= 2015-12-15T00:00:00Z];

My where is where I'm running into an issue. When I use Id in :ta I get the following

Invalid bind expression type of TopicAssignment for Id field of SObject FeedItem

and then when I try Id in :ta.EntityId I get

Initial term of field expression must be a concrete SObject: List

Could anyone please breakdown for me (in simple-ish terms) why this is happening and what I can do to fix? I realize that ta and cgf are lists, but shouldn't my where be able to compare to these lists? When I debug, I see the list but calling out the value I want isn't cutting it. Here's what the first query returns:

DEBUG|(TopicAssignment:{EntityId=0D53600000VqxQFCAZ, Id=0FT36000001AuzEGAS}, TopicAssignment:{EntityId=0D53600000VqxUlCAJ, Id=0FT36000001AuzJGAS}, TopicAssignment:{EntityId=0D53600000WXUzfCAH, Id=0FT36000001AvglGAC})
4
  • 1
    As a proposed solution, do I need to iterate through each returned list and put the variable I want into a new list? Then bind said new list?
    – Grant
    Oct 25, 2016 at 12:46
  • Yes, you need to extract related fields values
    – Patlatus
    Oct 25, 2016 at 12:55
  • 1
    You really really shouldn't use hard-coded ids. Anywhere. Ever.
    – Adrian Larson
    Oct 25, 2016 at 13:54
  • 1
    @AdrianLarson valid point. I will state that I have a personal dev org I'm testing in and it is easier to store the ids. It would've been smarter of me to name the values in my dev org the same as prod and use Name. Thank you for pointing this out.
    – Grant
    Oct 25, 2016 at 14:17

1 Answer 1

1

Please try this one

List<TopicAssignment> ta = [SELECT EntityId FROM TopicAssignment WHERE TopicId = '0TO30000000Xea1GAC'];
System.Debug(ta);
List<Id> fiList = new List<Id>();
for (TopicAssignment t: ta) {
    fiList.add( t.EntityId );
}
List<CollaborationGroupFeed> cgf = [select ParentId from CollaborationGroupFeed WHERE ParentId = '0F936000000cWkMCAU'];
System.Debug(cgf);
List<Id> piList = new List<Id>();
for (CollaborationGroupFeed c: cgf ) {
    piList.add( c.ParentId );
}
List<FeedItem> chatFeed = [SELECT  Id, Body, CommentCount, CreatedDate, LikeCount, LinkUrl, ParentId, RelatedRecordId, Title, Type,
                                (SELECT Id, CommentBody, CreatedDate, CreatedById, FeedItemId, ParentId FROM FeedComments)
                            FROM FeedItem 
                            WHERE (Id IN :fiList
                            OR ParentId in :piList)
                            AND CreatedDate >= 2015-12-15T00:00:00Z];

You could use list of SObject only if this is the same SObject.

So, if you do

List<FeedItem> feedItems = [SELECT Id FROM FeedItem WHERE Id IN: fiList ];

you could use either

WHERE (Id IN :fiList)

or

WHERE (Id IN :feedItems )

However, since SObject types are different, you can't put

WHERE (Id IN :cgf )

because here either List of Id is expected or List of FeedItem (which Salesforce can automatically transform to List of Id ) but List of TopicAssignment is not. Because there might be ambiguity if there were two different lookups to FeedItem then it won't be clear which one should be taken.

==============================================

Update.

This query [select ParentId from CollaborationGroupFeed WHERE ParentId = '0F936000000cWkMCAU']; just returns '0F936000000cWkMCAU' so it is possible to rewrite this using two queries

List<TopicAssignment> ta = [SELECT EntityId FROM TopicAssignment WHERE TopicId = '0TO30000000Xea1GAC'];
System.Debug(ta);
List<Id> fiList = new List<Id>();
for (TopicAssignment t: ta) {
    fiList.add( t.EntityId );
}

List<FeedItem> chatFeed = [SELECT  Id, Body, CommentCount, CreatedDate, LikeCount, LinkUrl, ParentId, RelatedRecordId, Title, Type,
                                (SELECT Id, CommentBody, CreatedDate, CreatedById, FeedItemId, ParentId FROM FeedComments)
                            FROM FeedItem 
                            WHERE (Id IN :fiList
                            OR ParentId = '0F936000000cWkMCAU')
                            AND CreatedDate >= 2015-12-15T00:00:00Z];
8
  • That was a good explanation, thank you. Is doing something like this a common practice? Or are multiple queries and lists considered 'rookie' and there are better alternatives?
    – Grant
    Oct 25, 2016 at 13:12
  • Generally you should try to have as little queries as you can to avoid hitting 101 SOQL Queries Governor Limit per transaction. Sometimes semi-joins query may help you to reduce number of queries, however, there are limitation on how complex semijoin query may be built.
    – Patlatus
    Oct 25, 2016 at 13:58
  • For example, you could try to write such semijoin query: SELECT Id, Body (SELECT Id FROM FeedComments) FROM FeedItem WHERE (Id IN ( SELECT EntityId FROM TopicAssignment WHERE TopicId = '0TO30000000Xea1GAC ) OR ParentId in ( select ParentId from CollaborationGroupFeed WHERE ParentId = '0F936000000cWkMCAU' ) ) AND CreatedDate >= 2015-12-15T00:00:00Z
    – Patlatus
    Oct 25, 2016 at 14:00
  • that is what I had tried originally, but I received the following error when trying: Semi join sub-selects are only allowed at the top level WHERE expressions and not in nested WHERE expressions but I understand where you're coming from with this.
    – Grant
    Oct 25, 2016 at 14:30
  • Yes, unfortunately you can't have smart query for this case. SOQL is very limited language and you can't do everything here in a one query like you could using SQL. However, if you had some different case where only one semijoin query was needed, you could do it in one query.
    – Patlatus
    Oct 26, 2016 at 12:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.