#dictionary #salesforce #apex #soql
Вопрос:
- Это прекрасно работает в песочнице, но вызывает слишком много ошибок soql в производстве. Я пытался использовать 2. увеличенную карту со ссылкой на распространение контента с запросом soql, но она всегда блокировала объем на КАРТЕ. есть какие-нибудь советы ?
- Так как я перепробовал все с помощью списка CustomObject__c=[select… contentdistribution := ..id], но это также дает слишком много soql 101
@RestResource(сопоставление URL=’/API/V1/уведомление/*’) глобальный с общим классом API_Notice {
@HttpGet(UrlMapping='/API/V1/notice/all')
global static List<String> getNotice(){
List<Object> senderJson = new List<Object>();
for (Notice__c a: [SELECT Name, ClosingDate__c,Contents__c, NoticeTypes__c,createddate,OfficialSenders__c,id,(SELECT ContentDocumentId FROM ContentDocumentLinks) FROM Notice__c]) {
List<Object> multipleAcct = new List<Object>();
NoticeWrapper nw = new NoticeWrapper();
Set<Id> contentsId = new Set<Id>();
List<Object> urls = new List<Object>();
Set<Id> acctId = new Set<Id>();
for(ContentDocumentLink cdl: a.ContentDocumentLinks){
if(cdl.ContentDocumentId!=null){
contentsId.add(cdl.ContentDocumentId);
}
}
if(a.OfficialSenders__c != null){
acctId.add(a.OfficialSenders__c);
}
if(a.id!=null){
nw.noticeid = a.Id;
}
if(a.ClosingDate__c != null){
nw.ClosingDate = a.ClosingDate__c;
}
if(a.NoticeTypes__c != null) {
nw.NoticeTypes = a.NoticeTypes__c;
}
if(a.Contents__c !=null){
nw.Contents = a.Contents__c;
}
if(a.Name !=null) {
nw.Name = a.Name;
}
if(a.CreatedDate !=null){
nw.createddate = a.createddate;
}
if(!acctId.isEmpty()){
Map<Id,CampaignMember> camplinks = new Map<Id,CampaignMember>([
select accountid ,CampaignId from CampaignMember where CampaignId IN: acctId
]);
if(!camplinks.isEmpty()){
for(CampaignMember cm : camplinks.values()){
multipleAcct.add(cm.AccountId);
nw.accountId = multipleAcct;
}
}
}
if(!contentsId.isEmpty() amp;amp; contentsid!=null){
Map<Id,ContentDistribution> links = new Map<Id,ContentDistribution>([
select id , distributionPublicURL,ContentDocumentId from contentDistribution where ContentDocumentId IN: contentsId
]);
if(!links.isEmpty()){
for(contentDistribution cdb : links.values()){
urls.add(cdb.DistributionPublicUrl);
nw.DistributionPublicUrl = urls;
}
}
}
senderJson.add(nw);
}
List<String> sends = new List<String>();
for(Object json : senderJson){
sends.add(String.valueof(json));
}
return sends;
}
@HttpPost
global static List<String> getOneNotice(String Id){
List<Object> urls = new List<Object>();
List<Object> senderJson = new List<Object>();
List<Object> multipleAcct = new List<Object>();
for (Notice__c a: [SELECT Name, ClosingDate__c,Contents__c,OfficialSenders__c, id,(SELECT ContentDocumentId FROM ContentDocumentLinks) FROM Notice__c where id=:id]) {
Set<Id> acctId = new Set<Id>();
Set<Id> contentsId = new Set<Id>();
NoticeWrapper nw = new NoticeWrapper();
nw.noticeid = a.Id;
nw.ClosingDate = a.ClosingDate__c;
nw.Contents = a.Contents__c;
nw.Name = a.Name;
for(ContentDocumentLink cdl: a.ContentDocumentLinks){
if(cdl.ContentDocumentId!=null){
contentsId.add(cdl.ContentDocumentId);
}
}
if(a.OfficialSenders__c != null){
acctId.add(a.OfficialSenders__c);
}
if(!acctId.isEmpty()){
Map<Id,CampaignMember> camplinks = new Map<Id,CampaignMember>([
select accountid ,CampaignId from CampaignMember where CampaignId IN: acctId
]);
if(!camplinks.isEmpty()){
for(CampaignMember cm : camplinks.values()){
multipleAcct.add(cm.AccountId);
nw.accountId = multipleAcct;
}
}
}
if(!contentsId.isEmpty()){
Map<Id,ContentDistribution> links = new Map<Id,ContentDistribution>([
select id , distributionPublicURL,ContentDocumentId from contentDistribution where ContentDocumentId IN: contentsId
]);
if(!links.isEmpty()){
for(contentDistribution cdb : links.values()){
urls.add(cdb.DistributionPublicUrl);
nw.DistributionPublicUrl = urls;
}
}
}
senderJson.add(nw);
}
List<String> sends = new List<String>();
for(Object json : senderJson){
sends.add(String.valueof(json));
}
return sends;
}
}
Ответ №1:
Контур вашей петли выглядит так
for (Notice__c a: [SELECT Name, ClosingDate__c,Contents__c, NoticeTypes__c,createddate,OfficialSenders__c,id,(SELECT ContentDocumentId FROM ContentDocumentLinks) FROM Notice__c]) {
// ...
if(!acctId.isEmpty()){
Map<Id,CampaignMember> camplinks = new Map<Id,CampaignMember>([
select accountid ,CampaignId from CampaignMember where CampaignId IN: acctId
]);
}
if(!contentsId.isEmpty() amp;amp; contentsid!=null){
Map<Id,ContentDistribution> links = new Map<Id,ContentDistribution>([
select id , distributionPublicURL,ContentDocumentId from contentDistribution where ContentDocumentId IN: contentsId
]);
}
// ...
senderJson.add(nw);
}
Таким образом, это 2 запроса в каждой итерации цикла, он взорвется после 50 Notice__c
записей. Возможно, вам удастся немного оптимизировать его, но скоро вы достигнете другого предела, например, 50 тысяч строк, запрашиваемых в одной транзакции. После того, как вам действительно понадобится некоторая оптимизация, возможно, подумайте о создании мини-объектов JSON, когда люди редактируют данные, и хранении их в вспомогательном текстовом поле внутри Notice__c
? Тогда API может просто запросить их готовность.
Проверьте, будет ли что — то подобное работать лучше.
// 1. Query all notices.
// 2. Loop through them once to pull the Ids of related records we need to query.
// 3. Query the related stuff once and put it in a map we can easily access.
// 4. Then loop notices again, building the final JSON message.
// 1
List<Notice__c> notices = [SELECT Name, ClosingDate__c,Contents__c, NoticeTypes__c, createddate,
OfficialSenders__c, id,
(SELECT ContentDocumentId FROM ContentDocumentLinks)
FROM Notice__c];
Map<Id, Campaign> campaigns = new Map<Id, Campaign>();
Map<Id, ContentDocument> contentdocs = new Map<Id, ContentDocument>();
// 2
for (Notice__c a: notices){
campaigns.put(a.OfficialSenders__c, null);
for(ContentDocumentLink cdl: a.ContentDocumentLinks){
contentdocs.put(cdl.ContentDocumentId, null);
}
}
campaigns.remove(null); // who needs ifs in the loop if you can just remove them once afterwards
contentdocs.remove(null);
// 3a - Campaigns
if(!campaigns.isEmpty()){
campaigns = new Map<Id, Campaign>([SELECT Id,
(SELECT AccountId FROM CampaignMembers WHERE AccountId != null)
FROM Campaign
WHERE Id IN :campaigns.keyset()]);
}
// 3b - download links
if(!contentdocs.isEmpty()){
contentdocs = new Map<Id, ContentDocument>([SELECT Id,
(SELECT distributionPublicURL FROM ContentDistributions WHERE distributionPublicURL != null)
FROM ContentDocument
WHERE Id IN :contentdocs.keyset()]);
}
// 4
List<Object> senderJson = new List<Object>();
for (Notice__c a: notices){
// bla bla, I'm skipping the ifs
Id campaignId = a.OfficialSenders__c;
// 4a
if(campaigns.containsKey(campaignId)){
Campaign c = campaigns.get(campaignId);
Set<Id> accountIds = new Set<Id>();
for(CampaignMember cm : c.CampaignMembers){
accountIds.add(cm.AccountId);
}
// nw.accountId = accountIds;
}
// 4b
if(!a.ContentDocumentLinks.isEmpty()){
Set<String> urls = new Set<String>();
for(ContentDocumentLink cdl: a.ContentDocumentLinks){
Id cdi = cdl.ContentDocumentId;
if(contentdocs.containsKey(cdi)){
for(ContentDistribution cd : contentdocs.get(cdi).ContentDistributions){
urls.add(cd.distributionPublicURL);
}
}
}
// nw.DistributionPublicUrl = urls;
}
}
Комментарии:
1. Очень, очень ценю это , я пробовал таким образом, и это работает, спасибо