Buscar Datos Usando un Diccionario
Caso de Uso
En este patrón, un registro de origen no contiene todos los datos requeridos por el destino. Por ejemplo, en el caso de una relación principal-secundario, si un registro secundario se va a actualizar en un destino, normalmente el destino requiere una referencia de registro principal. O, si trabaja con un registro de producto, el registro de origen puede tener solo un número de SKU, pero el destino también quiere una referencia de grupo o clase.
Una forma de manejar esto es realizar una búsqueda en línea o dinámica, mediante la inserción de una llamada de función en la transformación, de modo que a medida que se lee cada registro, se realiza una búsqueda en un objeto diferente y ese valor se completa en el campo. Las funciones que pueden realizar esto son:
- BúsquedaDB es útil para obtener un solo campo en una fuente de base de datos.
- DBBuscarTodo y DBExecute, son útiles si es necesario obtener más de un campo.
- Si SFDC tiene los datos necesarios, entonces SFLookup, SFBuscarTodo y SFCacheLookup puede ser usado. SFCacheLookup tiene la eficiencia adicional del almacenamiento en caché, de modo que el proceso de inicio de sesión se puede omitir si la sesión de SFDC aún está activa.
Sin embargo, el uso de estas funciones tiene un costo. Tome el uso de SFLookup en una transformación como ejemplo, donde se usa para obtener una ID de un objeto. Cuando un conjunto de datos de origen se pasa a través de una transformación, cada registro se evalúa y todas las funciones del secuencia de comandos se ejecutan individualmente. Si hay 10 registros para procesar, habrá 10 llamadas a SFDC. Si la integración procesa una pequeña cantidad de registros, usar búsquedas en línea es una excelente solución. Pero, ¿qué pasa si el universo de valores de búsqueda válidos no es 1000, sino que se van a procesar 10 000 registros? Realizar 10 000 llamadas adicionales en una transformación, donde cada llamada toma al menos un segundo, es muy ineficiente y lento. La forma mucho mejor es pagar la pequeña penalización de tiempo para buscar los 1000 registros en un diccionario y usarlo para las búsquedas.
¿qué Es un Diccionario en Jitterbit?
En Jitterbit, un diccionario es un tipo especial de matriz de variables globales que contiene un par clave-valor. Los pasos y funciones son:
- Inicializar el diccionario usando el Dict función.
- Cargue datos con pares clave-valor, como '4011' y 'Banana', '4061' y 'Lettuce', '4063' y 'Tomato', etc. Utilice AddtoDict función.
- Busque una clave después de verificar primero si la clave ya existe usando HasKey función.
- Buscar datos pasando la clave (4011) y recuperando el valor (Banana). El secuencia de comandos usa un '
[ ]
' después del nombre del diccionario, como:$value
=$d["4011"]
Un diccionario habilita nuestro escenario de tal manera que una operación puede obtener datos de la fuente y cargar el diccionario, poniéndolo a disposición de otras operaciones para búsquedas. Una operación inicial puede cargar el diccionario con 10.000 registros y una operación posterior puede pasar rápidamente una clave al diccionario y obtener un valor.
Una serie de cosas a tener en cuenta con los diccionarios:
- El ámbito de los diccionarios se limita a la instancia de la cadena de operaciones. Por ejemplo, si la operación A carga
$MyDict
con 10.000 registros, solo tendrán acceso a ese diccionario aquellas operaciones que estén vinculadas mediante rutas de Éxito o Fallo, o con RunOperation(). Pero, si una operación usa fragmentación de datos y subprocesamiento, y tiene una transformación que llena un diccionario, el diccionario será inconsistente. Esto se debe a que Jitterbit no toma los valores asignados a las variables por múltiples subprocesos de operación y los concatena en un solo conjunto de valores. Esto es cierto para todas las variables o matrices globales. Utilice los valores predeterminados de fragmentación de datos/subproceso al crear una operación que rellene los diccionarios. - Los diccionarios, debido a que utilizan una búsqueda binaria, son muy rápidos para encontrar claves y devolver valores. Por lo general, se puede encontrar una clave en cinco o seis intentos. Por el contrario, compare este tipo de búsqueda con recorrer una matriz de 10.000 registros para encontrar una clave.
- Los diccionarios no se escriben en la memoria, por lo que no afectarán materialmente la memoria del servidor disponible para el procesamiento.
Ejemplo 1
El cliente tiene dos tablas, una con información de productos y otra con categorías de productos, ambas necesarias para actualizar una tercera tabla. El origen es una vista de un almacén de datos, que está optimizado para proporcionar datos de forma masiva, pero no para búsquedas rápidas. Usar la función DBLookup para miles de registros sería bastante lento. Además, el cliente tiene un archivo CSV que contiene información utilizada para filtrar datos de la fuente
PWE.01 Obtener Lista LR
- Esto lee un archivo externo en el almacenamiento temporal
PWE.02 Establecer Dictado de Producto
- Un secuencia de comandos inicializa el Diccionario:
$Product.Dict.LR_List=Dict();
- Lee desde un archivo temporal fuente
- La Transformación carga los valores en un diccionario:
-
Secuencia de Comandos:
AddtoDict($Product.Dict.LR_List,Style_Color,Flag+"|"+Launch_Release_Date);
-
Tenga en cuenta aquí que el valor es en realidad 2 valores, separados por un '|'. La alternativa sería crear 2 diccionarios, uno para Flag y otro para Launch_Release_Date, lo que sería una complejidad innecesaria.
PWE.03 Producto de Consulta de Teradata
- La transformación tiene una condición para filtrar productos que no están en el archivo CSV, y que también asigna valores a las variables que se utilizan en la transformación.
- Tenga en cuenta que estamos dividiendo (con un '|') lo que se cargó en la operación anterior y cargándolo en $Product.Flag y $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 Categorías de Productos
Esta es una consultar SFDC masiva (no SOAP), que no afecta los límites de la API del cliente. Carga datos en un archivo temporal local.
PWE.05 Dictamen de Categoría de Producto
- Esto carga un diccionario con el Código como clave y los datos de SFDC como valor
$Code__c=Code__c;
AddToDict($Dict.Product.Category.Line, $Code__c, Id)
PWE.06 Estilo de Proceso
- El diccionario se inicializa:
$Style.Dict.Unique=Dict();
- La Transformación busca el ID en el 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
- Tenga en cuenta el uso de HasKey para verificar si la clave existe, en lugar de solo ...
$Dict.Product.Category.Line[$GBL_CAT_CORE_FOCS_CD].
- Si se pasa una clave que no existe en el diccionario, se arrojará un error ya que estamos tratando de buscar un valor que no existe.
PWE.07 Estilos de Inserción Masiva
- Finalmente, el archivo se carga de forma masiva en SFDC.
Ejemplo 2
En este ejemplo, estamos procesando una respuesta XML, extrayendo los SKU y los valores en un diccionario para usarlos en una operación posterior.
- Este secuencia de comandos está en el penúltimo secuencia de comandos postoperatorio:
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 secuencia de comandos hace varias cosas, por lo que estos comentarios se refieren a las acciones realizadas en relación con los diccionarios.
- Se inicializa el diccionario DCL.LineItem.
- Las variables locales 'mysku' y 'myquantity' se completan desde la fuente XML.
- DCL.LineItem se completa con 'mysku' como clave y 'myquantity' como valor.
- El diccionario se utiliza en una operación posterior, F.5.2.4
- La transformación muestra la asignación a Cantidad enviada.
- La secuencia de comandos ShippedQty utiliza el campo de origen como clave para recuperar la cantidad enviada y completar el valor.
- Tenga en cuenta que verificamos (usando HasKey) si la clave existe o no.
$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