Pesquise dados usando um dicionário no Jitterbit Design Studio
Caso de uso
Nesse padrão, um registro de origem não contém todos os dados exigidos pelo destino. Por exemplo, no caso de um relacionamento pai-filho, se um registro filho deve ser atualizado em um destino, normalmente uma referência de registro pai é exigida pelo destino. Ou, se estiver trabalhando com um registro de produto, o registro de origem pode ter apenas um número SKU, mas o destino também quer uma referência de grupo ou classe.
Uma maneira de lidar com isso é fazer uma pesquisa dinâmica ou em linha, inserindo uma chamada de função na transformação, de modo que, à medida que cada registro é lido, uma pesquisa é feita para um objeto diferente, e esse valor é preenchido no campo. As funções que podem executar isso são:
- DBLookup é útil para obter um único campo em uma fonte de banco de dados.
- DBLookupAll e DBExecute, são úteis se mais de um campo precisa ser buscado.
- Se SFDC contém os dados necessários, então SFLookup, SFLookupAll e SFCacheLookup poderia ser usado. O SFCacheLookup tem a eficiência adicional de cache, de modo que o processo de login pode ser ignorado se a sessão SFDC ainda estiver ativa.
No entanto, há um custo para usar essas funções. Tome como exemplo o uso de SFLookup em uma transformação, onde ele está sendo usado para obter um ID de um objeto. Quando um conjunto de dados de origem é passado por uma transformação, cada registro é avaliado e todas as funções de script são executadas individualmente. Se houver 10 registros a serem processados, haverá 10 chamadas para SFDC. Se a integração processar um pequeno número de registros, usar pesquisas em linha é uma ótima solução. Mas e se o universo de valores de pesquisa válidos não for 1.000, mas 10.000 registros a serem processados? Executar 10.000 chamadas adicionais em uma transformação, onde cada chamada leva pelo menos um segundo, é muito ineficiente e lento. A maneira muito melhor é pagar a pequena penalidade de tempo para pesquisar os 1.000 registros em um dicionário e usá-lo para pesquisas.
O que é um dicionário no Jitterbit?
No Jitterbit, um dicionário é um tipo especial de array de variáveis globais que contém um par chave-valor. Os passos e funções são:
- Inicialize o dicionário usando o Dict função.
- Carregue dados com pares de chave-valor, como '4011' e 'Banana', '4061' e 'Alface', '4063' e 'Tomate', etc. Use a função AddtoDict função.
- Procure uma chave após verificar primeiro se a chave já existe usando a função HasKey função.
- Pesquisar dados passando a chave (4011) e obtendo o valor (Banana). O script usa um '
[ ]
' após o nome do dicionário, como:$value
=$d["4011"]
Um dicionário habilita nosso cenário de modo que uma operação pode obter dados da fonte e carregar o dicionário, tornando-os disponíveis para outras operações para pesquisas. Uma operação inicial pode carregar o dicionário com 10.000 registros e uma operação posterior pode passar rapidamente uma chave para o dicionário e obter um valor.
Algumas coisas a ter em mente com relação aos dicionários:
- O escopo dos dicionários é limitado à instância da cadeia de operações. Por exemplo, se a operação A carrega
$MyDict
com 10.000 registros, apenas as operações que são vinculadas usando caminhos Success ou Failure, ou com RunOperation() terão acesso a esse dicionário. Mas, se uma operação usa fragmentação de dados e threading, e tem uma transformação que preenche um dicionário, o dicionário será inconsistente. Isso ocorre porque o Jitterbit não pega os valores atribuídos a variáveis por vários threads de operação e concatena em um único conjunto de valores. Isso é verdadeiro para todas as variáveis globais ou matrizes. Use os valores padrão fragmentação de dados/threading ao construir uma operação que preenche dicionários. - Dicionários, por usarem uma busca binária, são muito rápidos em encontrar chaves e retornar valores. Uma chave pode ser encontrada geralmente em cinco a seis tentativas. Em contraste, compare esse tipo de busca a um loop por uma matriz de 10.000 registros para encontrar uma chave.
- Os dicionários não são gravados na memória, portanto não impactarão materialmente a memória disponível do servidor para processamento.
Exemplo 1
O cliente tem duas tabelas, uma com informações do produto e a outra com categorias de produtos, ambas necessárias para atualizar uma terceira tabela. A fonte é uma visualização em um data warehouse, que é otimizada para fornecer dados em massa, mas não para pesquisas rápidas. Usar a função DBLookup para milhares de registros seria bem lento. Além disso, o cliente tem um arquivo CSV que contém informações usadas para filtrar dados da fonte
PWE.01 Obter lista LR
- Isso lê um arquivo externo em um armazenamento temporário
PWE.02 Definir produto Dict
- Um script inicializa o Dicionário:
$Product.Dict.LR_List=Dict();
- Lê de um arquivo temporário de origem
- A Transformação carrega os valores em um dicionário:
-
Script:
AddtoDict($Product.Dict.LR_List,Style_Color,Flag+"|"+Launch_Release_Date);
-
Note aqui que o valor é, na verdade, 2 valores, separados por '|'. A alternativa seria criar 2 dicionários, um para Flag e outro para Launch_Release_Date, o que seria uma complexidade desnecessária.
PWE.03 Consultar produto da Teradata
- A transformação tem uma condição para filtrar produtos que não estão no arquivo CSV e que também atribui valores às variáveis que são usadas na transformação.
- Observe que estamos dividindo (com '|') o que foi carregado na operação anterior e carregando em $Product.Flag e $Product.ReleaseDate.
result=false;
$Product.Dict.Key=PROD_CD;
If(HasKey($Product.Dict.LR_List,$Product.Dict.Key),
result=true;
value=$Product.Dict.LR_List[$Product.Dict.Key];
arr=Split(value,"|");
$Product.Flag=arr[0];
$Product.ReleaseDate=arr[1];
);
result
PWE.04 Consulta de categorias de produtos
Esta é uma consultar SFDC em massa (não SOAP), que não impacta os limites da API do cliente. Ela carrega dados em um arquivo temporário local.
PWE.05 Categoria de produto Dict
- Isso carrega um dicionário com o Código como uma chave e os dados SFDC como um valor
$Code__c=Code__c;
AddToDict($Dict.Product.Category.Line, $Code__c, Id)
PWE.06 Estilo de Processo
- O dicionário é inicializado:
$Style.Dict.Unique=Dict();
- A Transformação procura o ID no campo Product_Category
$GBL_CAT_CORE_FOCS_CD=GBL_CAT_CORE_FOCS_CD;
If(HasKey($Dict.Product.Category.Line,$GBL_CAT_CORE_FOCS_CD),result=$Dict.Product.Category.Line[$GBL_CAT_CORE_FOCS_CD],result="");
result
- Observe o uso de HasKey para verificar se a chave existe, em vez de apenas ...
$Dict.Product.Category.Line[$GBL_CAT_CORE_FOCS_CD].
- Se uma chave for passada que não existe no dicionário, então um erro será lançado, pois estamos tentando procurar um valor inexistente.
PWE.07 Estilos de Upsert em massa
- Finalmente o arquivo é carregado em massa para o SFDC.
Exemplo 2
Neste exemplo, estamos processando uma resposta XML, extraindo os SKUs e valores em um dicionário para uso em uma operação posterior.
- Este script está no penúltimo script pós-operatório:
arr=Array();
$jitterbit.scripting.while.max_iterations=10000;
arr=Split($IFMS.Response,'<');
cnt=Length(arr);i=0;j=0;
$DCL.LineItem=Dict();
While(i<cnt,
If(CountSubString(arr[i],'RemoteOrderNumber xmlns=""')==1,
order=arr[i];
start=Index(order,'>');
end=Length(order);
myorder=Mid(order,start+1,(end-1)-start);
$ACM.Shipment.Number=myorder;
);
If(CountSubString(arr[i],'ShipDate xmlns=""')==1,
shipdate=arr[i];
start=Index(shipdate,'>');
end=Length(shipdate);
shipdate=Mid(shipdate,start+1,(end-1)-start);
if(Length(shipdate)>7,
shipdate=Left(shipdate, Index(shipdate, ' '));
shipdate=CVTDate(shipdate,'?m/?d/yyyy','yyyy-mm-dd');
);
$ACM.ShipDate=shipdate;
WriteToOperationLog("Shipment: "+myorder+" ShipDate: "+shipdate);
);
If(CountSubString(arr[i],'ShippingTrackingNumber xmlns=""')==1,
tracking=arr[i];
start=Index(tracking,'>');
end=Length(tracking);
tracking=Mid(tracking,start+1,(end-1)-start);
$ACM.Tracking.Number=tracking;
WriteToOperationLog("Shipment: "+myorder+" Tracking: "+tracking);
);
If(CountSubString(arr[i],'SKU xmlns=""')==1,
sku=arr[i];
start=Index(sku,'>');
end=Length(sku);
mysku=Mid(sku,start+1, (end-1)-start);
WriteToOperationLog("SKU: "+mysku);
j++;
);
If(CountSubString(arr[i],'QuantityShipped xmlns=""')==1,
qty=arr[i];
start=Index(qty,'>');
end=Length(qty);
myqty=Mid(qty,start+1, (end-1)-start);
WriteToOperationLog("QuantityShipped: "+myqty);
$DCL.LineItem[mysku]=myqty
);
If(CountSubString(arr[i],'/OrderList')==1,
WriteToOperationLog("End of OrderList. " + String(j) + " items found.");
$ACM.Login.Counter=1;
RunOperation("<TAG>Operations/2. Fulfillment/F.5.0.D Get Shipments</TAG>");
$DCL.LineItem=Dict();
);
++i);
- Este script faz uma série de coisas, então esses comentários se referem às ações tomadas em relação aos dicionários.
- O dicionário DCL.LineItem é inicializado.
- As variáveis locais 'mysku' e 'myquantity' são preenchidas a partir da fonte XML.
- DCL.LineItem é preenchido usando 'mysku' como chave e 'myquantity' como valor.
- O dicionário é usado em uma operação posterior, F.5.2.4
- A transformação exibe o mapeamento para Qtde Enviada.
- O script ShippedQty usa o campo de origem como uma chave para recuperar a quantidade enviada e preencher o valor.
- Observe que verificamos (usando HasKey) se a chave existe ou não.
$myVal=Envelope$Body$GetResponse$GetResult$Details$ShipmentDetail.InventoryID$Value$;
WriteToOperationLog("Shipped Qty: "+Envelope$Body$GetResponse$GetResult$Details$ShipmentDetail.ShippedQty$Value$+" ------- "+
"InventoryID: "+Envelope$Body$GetResponse$GetResult$Details$ShipmentDetail.InventoryID$Value$);
If(HasKey($DCL.LineItem, $myVal),
output=$DCL.LineItem[$myVal],
WriteToOperationLog("Could not find: "+$myVal+" in Dict");
output=0
);
output