2016-04-28 3 views
13


Ich begann vor kurzem mit der Implementierung von ElasticSearch (ES) in eine in PHP geschriebene E-Commerce-App mit MySQL. Ich bin völlig neu in all dem Zeug und das Lesen der Dokumente ist in Ordnung, aber ich brauche wirklich jemanden mit Erfahrung, um mich zu beraten.Wie man die ElasticSearch-Indexstruktur mit mehreren Entity-Bindings einrichtet

Aus der ES-Dokumentation konnte ich einen neuen Cluster erstellen und ich fand auch heraus, dass Flüsse veraltet sind und ersetzt werden sollten, also ersetzte ich sie durch Logstash und JDBC MySQL Connector.

An diesem Punkt habe ich:

  • Elasticsearch
  • Logstash
  • JDBC MySQL-Treiber
  • MySQL Server

Die Datenbankstruktur der Anwendung nicht wirklich optimal ist, und ist sehr schwer zu ersetzen, aber ich würde es gerne in den ES-Index bestmöglich replizieren.

DB Struktur:

Produkte

+-------------------------------+-------+--------+ 
|    Id    | Title | Price | 
+-------------------------------+-------+--------+ 
| 00c8234d71c4e94f725cd432ebc04 | Alpha | 589,00 | 
| 018357657529fef056cf396626812 | Beta | 355,00 | 
| 01a2c32ceeff0fc6b7dd4fc4302ab | Gamma | 0,00 | 
+-------------------------------+-------+--------+ 

Flags

+------------+-------------+ 
|  Id  | Title | 
+------------+-------------+ 
| sellout | Sellout  | 
| discount | Discount | 
| topproduct | Top Product | 
+------------+-------------+ 

flagsProducts (n: m Schwenk)

+------+-------------------------------+------------+------------+ 
| Id |   ProductId   | FlagId | ExternalId | 
+------+-------------------------------+------------+------------+ 
| 1552 | 00c8234d71c4e94f725cd432ebc04 | sellout | NULL  | 
| 2845 | 00c8234d71c4e94f725cd432ebc04 | topproduct | NULL  | 
| 9689 | 018357657529fef056cf396626812 | discount | NULL  | 
| 4841 | 01a2c32ceeff0fc6b7dd4fc4302ab | discount | NULL  | 
+------+-------------------------------+------------+------------+ 

Diese String-IDs sind ein komplettes Desaster (aber ich muss mich jetzt damit befassen). Zuerst dachte ich, ich sollte eine flache Struktur des Products-Index für ES erstellen, aber was ist mit Mehrfach-Entity-Bindings?

+0

Wenn Sie Ihre MySQL-Daten auf ES verschieben möchten: https://sysadminci.wordpress.com/2016/01/06/import-mysql-data-in-elasticsearch-server/ –

+0

Die flache Datenstruktur scheint am besten zu sein Ansatz so weit. Gibt es besondere Anforderungen an Abfragen für diesen Index? Wenn Sie über die Datenstruktur in ES nachdenken, müssen Sie auch über die Abfragen nachdenken, die Sie verwenden möchten. –

+0

@fagnyr, du hast dich in den letzten 7 Tagen bezüglich deiner Frage nicht gemeldet. Gibt es weitere Informationen, die Sie benötigen? – Val

Antwort

10

Das ist ein guter Start!

Ich würde es auf jeden Fall flach machen (d. H. denormalize) und mit Produktdokumenten kommen, die wie die untenstehende aussehen. Auf diese Weise werden Sie die N: M-Beziehung zwischen Produkten und Flags los, indem Sie einfach ein flags Array für jedes Produkt erstellen. Es wird daher einfacher sein, diese Flags abzufragen.

{ 
    "id": "00c8234d71c4e94f725cd432ebc04", 
    "title": "Alpha", 
    "price": 589.0, 
    "flags": ["Sellout", "Top Product"] 
} 
{ 
    "id": "018357657529fef056cf396626812", 
    "title": "Beta", 
    "price": 355.0, 
    "flags": ["Discount"] 
} 
{ 
    "id": "01a2c32ceeff0fc6b7dd4fc4302ab", 
    "title": "Gamma", 
    "price": 0.0, 
    "flags": ["Discount"] 
} 

Das Produkt Mapping-Typ würde wie folgt aussehen:

PUT products 
{ 
    "mappings": { 
     "product": { 
      "properties": { 
       "id": { 
        "type": "string", 
        "index": "not_analyzed" 
       }, 
       "title": { 
        "type": "string" 
       }, 
       "price": { 
        "type": "double", 
        "null_value": 0.0 
       }, 
       "flags": { 
        "type": "string", 
        "index": "not_analyzed" 
       } 
      } 
     } 
    } 
} 

Da Sie den logstash jdbc Eingang bereits haben, alles, was Sie fehlt die richtige SQL-Abfrage ist, die Produkte und die damit verbundene Fahnen zu holen.

SELECT p.Id as id, p.Title as title, p.Price as price, GROUP_CONCAT(f.Title) as flags 
    FROM Products p 
    JOIN flagsProducts fp ON fp.ProductId = p.Id 
    JOIN Flags f ON fp.FlagId = f.id 
GROUP BY p.Id 

Welche Sie Zeilen wie diese bekommen würde:

+-------------------------------+-------+-------+---------------------+ 
| id       | title | price | flags    | 
+-------------------------------+-------+-------+---------------------+ 
| 00c8234d71c4e94f725cd432ebc04 | Alpha | 589 | Sellout,Top product | 
| 018357657529fef056cf396626812 | Beta | 355 | Discount   | 
| 01a2c32ceeff0fc6b7dd4fc4302ab | Gamma |  0 | Discount   | 
+-------------------------------+-------+-------+---------------------+ 

Logstash Filter verwenden, können Sie spalten dann die flags in ein Array und Sie sind gut zu gehen.

+0

Würde es bedeuten, dass das "Flags" Mapping Array statt String sein sollte, da ich Logstash Filter angewendet habe? – falnyr

+0

String ist in Ordnung, ES erstellt in Ihrem Auftrag ein Array von Strings. – Val