Pipeline d'index d'attribut Ingest

Les mappages de données complets à partir de la spécification, de la base de données et du schéma sont affichés pour la catégorie Attribut.

Mappage de la zone d'index d'attribut à partir de la base de données

La séquence d'étapes suivante illustre le pipeline d'indexation Attribut implémenté dans Apache NiFi. Pour plus d'informations sur l'appel du service Ingest, voir Rechercher l'API de service Ingest. Pour une liste complète des zones et des paramètres d'index Elasticsearch, voir Types de zones d'index Elasticsearch.

Le flux se compose principalement de deux étapes :
  1. Création d'un document Attribut
  2. Association de valeurs d'attribut

Etape 1 : Création d'un document Attribut

Cette étape décrit comment les données Attribut peuvent être transformées et chargées dans l'index Attribut. Il commence par exécuter l'instruction SQL suivante pour récupérer les données Attribut depuis la base de données Commerce.
 SELECT A.ATTR_ID, COALESCE(AD.LANGUAGE_ID, L.LANGUAGE_ID) LANGUAGE_ID, 
		A.STOREENT_ID, A.ATTRTYPE_ID, A.ATTRUSAGE, A.IDENTIFIER, A.SEQUENCE ATTR_SEQUENCE,
		A.DISPLAYABLE, A.SEARCHABLE, A.COMPARABLE, A.FACETABLE, A.MERCHANDISABLE, A.SWATCHABLE, 
		AD.NAME, AD.DESCRIPTION, AD.GROUPNAME, QD.QTYUNIT_ID, QD.DESCRIPTION QTY_DESCRIPTION, 
        L.LOCALENAME, F.MAX_DISPLAY, F.SELECTION,
		F.SEQUENCE FACET_SEQUENCE, F.FACET_ID, F.SORT_ORDER, F.ZERO_DISPLAY, F.GROUP_ID, F.KEYWORD_SEARCH,
		LOWER(S.SRCHFIELDNAME) || '_ntk_cs' FIELDNAME, A.STOREDISPLAY
	      FROM LANGUAGE L, ATTR A
	    	   LEFT JOIN ATTRDESC AD ON (A.ATTR_ID = AD.ATTR_ID AND AD.LANGUAGE_ID = ${param.langId})
	    	   LEFT JOIN QTYUNITDSC QD ON (AD.QTYUNIT_ID = QD.QTYUNIT_ID AND QD.LANGUAGE_ID = AD.LANGUAGE_ID)
	    	   LEFT JOIN FACET F ON (A.ATTR_ID = F.ATTR_ID AND
	    	 					     F.STOREENT_ID IN (SELECT RELATEDSTORE_ID FROM STOREREL
	    	 					   					    WHERE STATE = 1 AND STRELTYP_ID = -4 AND STORE_ID = ${param.storeId}))
	    	   LEFT JOIN ATTRDICTSRCHCONF S ON (A.ATTR_ID = S.ATTR_ID AND
	    	                                    S.MASTERCATALOG_ID IN (SELECT C.CATALOG_ID FROM STORECAT C
	    	                                                            WHERE C.MASTERCATALOG = 1 AND C.STOREENT_ID IN 
	                                                                          (SELECT RELATEDSTORE_ID FROM STOREREL
	                                                                            WHERE STATE = 1 AND STRELTYP_ID = -4
	                                                                              AND STORE_ID = ${param.storeId})))
	     WHERE A.STOREENT_ID IN (SELECT RELATEDSTORE_ID FROM STOREREL
	    	 					    WHERE STATE = 1 AND STRELTYP_ID = -4 AND STORE_ID = ${param.storeId}) AND L.LANGUAGE_ID = ${param.langId} ${extAttributeAnd}
         UNION
        SELECT S.SRCHATTR_ID, L.LANGUAGE_ID, ${param.storeId}, NULL, NULL, 'facet' || TO_CHAR(S.SRCHATTR_ID), NULL,
               1, 1, NULL, 1, NULL, 0, D.NAME, D.DESCRIPTION, NULL, NULL, NULL,  L.LOCALENAME, F.MAX_DISPLAY, F.SELECTION,
	           F.SEQUENCE FACET_SEQUENCE, F.FACET_ID, F.SORT_ORDER, F.ZERO_DISPLAY, F.GROUP_ID, F.KEYWORD_SEARCH, S.PROPERTYVALUE, 0
          FROM SRCHATTRPROP S, SRCHATTR A, FACET F, FACETDESC D, LANGUAGE L
         WHERE S.PROPERTYNAME = 'facet' AND S.PROPERTYVALUE NOT LIKE 'ad%' AND S.PROPERTYVALUE NOT LIKE 'price_%'
           AND S.SRCHATTR_ID = A.SRCHATTR_ID AND A.SRCHATTR_ID = F.SRCHATTR_ID
           AND (A.INDEXSCOPE IN   
		       (SELECT C.CATALOG_ID FROM STORECAT C
		         WHERE C.MASTERCATALOG = 1 AND C.STOREENT_ID IN
		               (SELECT RELATEDSTORE_ID FROM STOREREL
		                 WHERE STATE = 1 AND STRELTYP_ID = -4 AND STORE_ID = ${param.storeId}))
		    OR  A.INDEXSCOPE = 0)
		   AND L.LANGUAGE_ID = ${param.langId} AND D.LANGUAGE_ID = L.LANGUAGE_ID AND F.FACET_ID = D.FACET_ID
         ORDER BY 1
 OFFSET ${param.offset} ROWS FETCH NEXT ${param.pageSize} ROWS ONLY         
                
Notez que la 2ème partie de l'expression UNION ci-dessus est utilisée pour inclure explicitement les entrées de facettes pour la marque, la catégorie et les prix. Ensuite, le jeu de résultats est transmis au processeur CreateAttributeDocumentFromDatabase pour transformation, à l'aide du tableau suivant pour ​mapper la zone de base de données renvoyée depuis l'instruction SQL ci-dessus vers une zone d'index dans l'index Attribut :​
Nom de zone d'index Type de zone d'index Description
Identificateur du document.
​id/store id_​string ID interne du magasin propriétaire ; mappé à ATTR.STOREENT_ID
id/​language id_​string L'identificateur de la langue ; mappé à ATTRDESC.LANGUAGE_ID
id/​attribute id_​string L'ID interne de l'attribut ; mappé à ATTR.ATTR_ID
​​identifier/specification id_​string Défini sur "attribut"
identifier/​store id_​string Une chaîne qui identifie de façon unique le magasin propriétaire ; mappé à ATTR.STOREENT_ID
identifier/​language id_​string Le paramètre régional linguistique de cet attribut ; mappé depuis ATTRDESC.LANGUAGE_ID
​identifier/attribute/raw ​​raw La forme originale de l'identifiant d'attribut ; mappé à ATTR.IDENTIFIER
​identifier/attribute/normalized normalisé Forme normalisée de l'identificateur d'attribut ; mappé à ATTR.IDENTIFIER
​​Données sensibles à la langue​​​
​name/raw ​​raw Le nom dépendant de la langue de cet attribut ; mappé à ATTRDESC.NAME
​​name/normalized normalized ​Identique à ci-dessus
​​description/raw ​​raw Une courte description de cet attribut ; mappé à ATTRDESC.DESCRIPTION
Propriétés
displayable boolean Identifie si cet attribut peut être affiché sur la vitrine ; mappé à ATTR.DISPLAYABLE
searchable boolean Identifie si cet attribut peut être recherché ; mappé à ATTR.SEARCHABLE
apte aux facettes boolean Spécifie que l'attribut est utilisé comme une facette dans la vitrine du magasin pour la navigation à facettes ; mappé à ATTR.FACETABLE
comparable boolean Identifie si cet attribut peut être utilisé pour la comparaison ; mappé à ATTR.COMPARABLE
commercialisable boolean Indique si l'attribut est utilisé dans la création de règles de marchandisage ; mappé à ATTR.MERCHANDISABLE
échantillonable boolean Identifie si cet attribut peut être affiché avec l'image d'échantillon ; mappé à ATTR.SWATCHABLE
ruban boolean ​Identifie si cet attribut peut être utilisé comme ruban pour l'affichage ; mappée à ATTR.STOREDISPLAY​
groupe id_string Spécifie le nom du groupe d'attributs. Tous les attributs apparentés doivent être créés avec le même nom de groupe.
​unit/identifier ​​id_string Les unités dans lesquelles cet attribut est mesuré ; mappé à ATTRDESC.QTYUNIT_ID
​unit/name/raw raw La description de cette unité de quantité ; mappé à QTYUNITDSC.DESCRIPTION
Données de navigation
sequence float L'ordre d'affichage des attributs dans un groupe d'attributs ou dans la racine du dictionnaire d'attributs ; ATTR.SEQUENCE
​facet/limit entier Les valeurs maximales à afficher dans la vitrine pour la facette ; mappé à FACET.MAX_DISPLAY
​facet/zero boolean Décrit si l'attribut apte aux facettes doit afficher des valeurs de comptage nulles ; mappé à FACET.ZERO_DISPLAY
​facet/multiple boolean Décrit si l'attribut apte aux facettes permet plusieurs sélections ; mappé à FACET.SELECTION
​facet/order entier L'ordre d'affichage à utiliser lors de l'affichage des valeurs de la facette ; mappé à FACET.SORT_ORDER
​facet/search boolean Décrit si la facette doit être incluse dans la recherche de mots clés ; mappé à FACET.KEYWORD_SEARCH
​​facet/sequence float La séquence de la facette affichée dans la vitrine ; mappé à FACET.SEQUENCE
​facet/key ​​id_string La clé normalisée utilisée pour les règles de recherche ; mappé à ATTRDICTSRCHCONF.SRCHFIELDNAME
​facet/group ​id_string​ L'identificateur de groupe interne de la facette à utiliser dans la vitrine ; mappé à FACET.GROUP_ID
Pour un exemple de code, voir Exemples d'étape 1.

Etape 2 : Association de valeurs d'attribut

Cette étape décrit comment les données de valeur Attribut peuvent être transformées et chargées dans l'index Attribut. Il commence par exécuter l'instruction SQL suivante pour récupérer les données de valeur Attribut depuis la base de données Commerce.
SELECT LISTAGG(V.IDENTIFIER, '###') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) ATTRVAL_IDENTIFIER,
	       LISTAGG(COALESCE(VD.STRINGVALUE, ' '), '###') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) STRINGVALUE, 
	       LISTAGG(COALESCE(TO_CHAR(VD.INTEGERVALUE), ' '), '###') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) INTEGERVALUE, 
	       LISTAGG(COALESCE(TO_CHAR(VD.FLOATVALUE), ' '), '###') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) FLOATVALUE, 
	       LISTAGG(TO_CHAR(VD.SEQUENCE), ', ') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) ATTRVAL_SEQUENCE, 
	       LISTAGG(COALESCE(VD.QTYUNIT_ID, ' '), '###') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) QTYUNIT_ID,
	       LISTAGG(COALESCE(NULLIF(VD.IMAGE1,''), ' '), '###') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) IMAGE1, 
	       LISTAGG(COALESCE(NULLIF(VD.IMAGE2,''), ' '), '###') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) IMAGE2,
	       LISTAGG(V.ATTRVAL_ID, ', ') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) ATTRVAL_ID,
	       LISTAGG(COALESCE(QD.DESCRIPTION, ' '), '###') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) QTY_DESCRIPTION,
	       LISTAGG(A.ATTRTYPE_ID, '###') WITHIN GROUP (ORDER BY V.ATTRVAL_ID) ATTRTYPE_ID,
	       A.ATTR_ID
	  FROM ATTR A, ATTRVAL V, ATTRVALDESC VD, QTYUNITDSC QD
	 WHERE A.ATTR_ID = V.ATTR_ID AND V.ATTRVAL_ID = VD.ATTRVAL_ID AND VD.LANGUAGE_ID = ${param.langId} 
	   AND VD.QTYUNIT_ID = QD.QTYUNIT_ID AND QD.LANGUAGE_ID = VD.LANGUAGE_ID
	   AND A.STOREENT_ID IN (SELECT RELATEDSTORE_ID 
	                           FROM STOREREL WHERE STATE = 1 AND STRELTYP_ID = -4 AND STORE_ID = ${param.storeId}) ${extAttributeAnd}
	 GROUP BY A.ATTR_ID
         ORDER BY A.ATTR_ID
         OFFSET ${param.offset} ROWS FETCH NEXT ${param.pageSize} ROWS ONLY​    ​   

Ensuite, le jeu de résultats est transmis au processeur FindAttributeValuesFromDatabase pour transformation, à l'aide du tableau suivant pour ​mapper la zone de base de données renvoyée depuis l'instruction SQL ci-dessus vers une zone d'index dans l'index Attribut :​

Nom de zone d'index Type de zone d'index Description
Valeurs d'attribut
values/id​ ​id_string​ L'ID unique interne pour cette valeur d'attribut ; mappé à ATTRVAL.ATTRVAL_ID
​​values/identifier ​​id_string L'identificateur externe de cette valeur d'attribut ; mappé à ATTRVAL.IDENTIFIER
​​​values/sequence​ float Un nombre qui détermine l'ordre d'affichage d'une liste de valeurs d'attributs admises pour un attribut spécifique ; mappé à ATTRVALDESC.SEQUENCE
​​​​​values/value/raw ​​id_string La valeur de chaîne de cette valeur d'attribut ; mappé à ATTRVALDESC.STRINGVALUE​, ATTRVALDESC.FLOATVALUE ou INTEGERVALUE
​​​​​values/value/normalized normalized Identique à ci-dessus
​​​​​values/value/image1 ​​raw Le chemin d'accès image1 de cette valeur d'attribut ; mappé à ATTRVALDESC.IMAGE1
​​​​​values/value/image2 ​​raw Le chemin d'accès image2 de cette valeur d'attribut ; mappé à ATTRVALDESC.IMAGE2
values/unit/identifier ​​id_string L'identificateur d'unité de mesure dans lequel cet attribut est mesuré ; mappé à ATTRVALDESC.QTYUNIT_ID
valeurs/unité/nom/brut raw La description de l'unité de quantité ; mappé à QTYUNITDSC.DESCRIPTION
Pour un exemple de code, voir Exemples d'étape 2.

Exemples d'étape 1

Le code suivant est un exemple des données d'entrée pour le processeur CreateAttributeDocumentFromDatabase.

{
  "LANGUAGE_ID": -1,
  "STOREENT_ID": 1,
  "ATTRTYPE_ID": null,
  "ATTR_ID": -1013,
  "ATTRUSAGE": null,
  "IDENTIFIER": "facet-1013               ",
  "ATTR_SEQUENCE": null,
  "DISPLAYABLE": 1,
  "SEARCHABLE": 1,
  "COMPARABLE": null,
  "FACETABLE": 1,
  "MERCHANDISABLE": null,
  "SWATCHABLE": 0,
  "NAME": "Category",
  "DESCRIPTION": "The category",
  "GROUPNAME": null,
  "QTYUNIT_ID": null,
  "QTY_DESCRIPTION": null,
  "LOCALENAME": "en_US           ",
  "MAX_DISPLAY": 20,
  "SELECTION": 0,
  "FACET_SEQUENCE": 0,
  "FACET_ID": -1001,
  "SORT_ORDER": 0,
  "ZERO_DISPLAY": 0,
  "GROUP_ID": 0,
  "KEYWORD_SEARCH": 1,
  "FIELDNAME": "parentCatgroup_id_search"
}
Le processeur CreateAttributeDocumentFromDatabase transforme les données d'entrée en données de sortie suivantes en fonction du tableau de mappage d'index :

{ "update": { "_id": "1--1--1013", "_index": ".auth.1.attribute.202006160325", "retry_on_conflict": 5, "_source": false } }
{
  "doc": {
    "identifier": {
      "specification": "attribute",
      "language": "en_US",
      "attribute": {
        "normalized": "facet-1013",
        "raw": "facet-1013"
      },
      "key": "facet-1013"
    },
    "sequence": 0,
    "name": {
      "normalized": "Category",
      "raw": "Category"
    },
    "displayable": true,
    "description": {
      "raw": "The category"
    },
    "facetable": true,
    "id": {
      "language": "-1",
      "attribute": "-1013",
      "store": "1"
    },
    "facet": {
      "zero": false,
      "sequence": 0,
      "search": true,
      "limit": 20,
      "multiple": false,
      "key": "parentCatgroup_id_search",
      "order": 0,
      "group": "0"
    },
    "searchable": true,
    "__meta": {
      "created": "2020-07-28T14:55:54.911Z",
      "modified": "2020-07-28T14:55:54.911Z",
      "version": {
        "min": 0,
        "max": 0
      }
    },
    "swatchable": false
  },
  "doc_as_upsert": true
}

Exemples d'étape 2

Le code suivant est un exemple des données d'entrée pour le processeur FindAttributeValuesFromDatabase.

{
  "ATTRVAL_IDENTIFIER": "Multi-color###Blue###Ivory###Light blue###Gray###White###Purple###Black###Denim###Taupe",
  "STRINGVALUE": "Multi-color###Blue###Ivory###Light blue###Gray###White###Purple###Black###Denim###Taupe",
  "INTEGERVALUE": " ### ### ### ### ### ### ### ### ### ",
  "FLOATVALUE": " ### ### ### ### ### ### ### ### ### ",
  "ATTRVAL_SEQUENCE": "1, 2, 3, 4, 5, 6, 7, 8, 9, 10",
  "QTYUNIT_ID": "C62             ###C62             ###C62             ###C62             ###C62             ###C62             ###C62             ###C62             ###C62             ###C62             ",
  "IMAGE1": " ### ### ### ### ### ### ### ### ### ",
  "IMAGE2": " ### ### ### ### ### ### ### ### ### ",
  "ATTRVAL_ID": "7000000000000000785, 7000000000000000786, 7000000000000000787, 7000000000000000788, 7000000000000000789, 7000000000000000790, 7000000000000000791, 7000000000000000792, 7000000000000000793, 7000000000000000794",
  "QTY_DESCRIPTION": "one###one###one###one###one###one###one###one###one###one",
  "ATTRTYPE_ID": "STRING          ###STRING          ###STRING          ###STRING          ###STRING          ###STRING          ###STRING          ###STRING          ###STRING          ###STRING          ",
  "ATTR_ID": 7000000000000000000
}
Le processeur FindAttributeValuesFromDatabase transforme les données d'entrée avec l'ID de magasin et l'ID de langue transmis depuis la classe NiFi FlowFile en tant qu'attributs de flux dans la sortie suivante :

{ "update": { "_id": "1--1-7000000000000000000", "_index": ".auth.1.attribute.202006160325", "retry_on_conflict": 5, "_source": false } }

{
  "doc": {
    "values": [
      {
        "identifier": "Multi-color",
        "sequence": 1,
        "unit": {
          "identifier": "C62",
          "name": {
            "raw": "one"
          }
        },
        "id": "7000000000000000785",
        "value": {
          "normalized": "Multi-color",
          "raw": "Multi-color"
        }
      },
      {
        "identifier": "Blue",
        "sequence": 2,
        "unit": {
          "identifier": "C62",
          "name": {
            "raw": "one"
          }
        },
        "id": "7000000000000000786",
        "value": {
          "normalized": "Blue",
          "raw": "Blue"
        }
      },
      {
        "identifier": "Ivory",
        "sequence": 3,
        "unit": {
          "identifier": "C62",
          "name": {
            "raw": "one"
          }
        },
        "id": "7000000000000000787",
        "value": {
          "normalized": "Ivory",
          "raw": "Ivory"
        }
      },
      {
        "identifier": "Light blue",
        "sequence": 4,
        "unit": {
          "identifier": "C62",
          "name": {
            "raw": "one"
          }
        },
        "id": "7000000000000000788",
        "value": {
          "normalized": "Light blue",
          "raw": "Light blue"
        }
      },
      {
        "identifier": "Gray",
        "sequence": 5,
        "unit": {
          "identifier": "C62",
          "name": {
            "raw": "one"
          }
        },
        "id": "7000000000000000789",
        "value": {
          "normalized": "Gray",
          "raw": "Gray"
        }
      },
      {
        "identifier": "White",
        "sequence": 6,
        "unit": {
          "identifier": "C62",
          "name": {
            "raw": "one"
          }
        },
        "id": "7000000000000000790",
        "value": {
          "normalized": "White",
          "raw": "White"
        }
      },
      {
        "identifier": "Purple",
        "sequence": 7,
        "unit": {
          "identifier": "C62",
          "name": {
            "raw": "one"
          }
        },
        "id": "7000000000000000791",
        "value": {
          "normalized": "Purple",
          "raw": "Purple"
        }
      },
      {
        "identifier": "Black",
        "sequence": 8,
        "unit": {
          "identifier": "C62",
          "name": {
            "raw": "one"
          }
        },
        "id": "7000000000000000792",
        "value": {
          "normalized": "Black",
          "raw": "Black"
        }
      },
      {
        "identifier": "Denim",
        "sequence": 9,
        "unit": {
          "identifier": "C62",
          "name": {
            "raw": "one"
          }
        },
        "id": "7000000000000000793",
        "value": {
          "normalized": "Denim",
          "raw": "Denim"
        }
      },
      {
        "identifier": "Taupe",
        "sequence": 10,
        "unit": {
          "identifier": "C62",
          "name": {
            "raw": "one"
          }
        },
        "id": "7000000000000000794",
        "value": {
          "normalized": "Taupe",
          "raw": "Taupe"
        }
      }
    ],
    "__meta": {
      "modified": "2020-07-28T15:18:30.965Z"
    }
  }
}