2016-04-27 2 views
3

Ich arbeite auf einem Suchserver so etwas wie elastische Suche. Nur ein kleines Projekt, das ich gerade entwickle. Habe die meisten Teile fertiggestellt, bin aber festgefahren, wie der Benutzer mit dem System interagieren würde.Erstellen Sie eine Abfragesprache mit Python

Ich entschied zunächst, dass der Benutzer anfordern würde, indem Sie eine JSON-Abfrage mit erforderlichen Feldern und seinen Werten senden. Aber das Problem, mit dem ich konfrontiert bin, ist, dass ich, obwohl ich Abfragen mit dem Json-Weg auswerten kann, nicht in der Lage wäre, Boolesche Abfragen und Compounf-Anweisungen zu implementieren.

Ich habe versucht, so etwas wie

index: name 
schema:name 
field1: value 
field 2: value 

aber es könnte auch so etwas wie diese, wenn Booleschen Ausdruck implementiert

index : name 
schema : name 
field 1 : name1 or name 2 
field 2: <9.22 and >=2.32 
field 3: (<9.22 and >=2.32) or (<100 and >90) // compound statement. 

Gibt es eine etwas einfache Möglichkeit, dies zu realisieren, ohne eine tatsächlich zu schaffen Abfragesprachgrammatik. Wenn ja, wie könnte ich das erreichen, wenn nicht dann auch dasselbe.

Ich dachte daran, Werte basierend auf und/oder von jedem Feld zu teilen, aber das würde nicht funktionieren, wenn es zusammengesetzte Aussagen gibt.

Ich habe auch Pyparsing ausgecheckt, aber ich konnte keinen funktionierenden Weg finden, das zu benutzen.

+0

Auschecken [whoosh] (https://bitbucket.org/mchaput/whoosh/wiki/Home) oder [plyse] (https://github.com/sebastiandev/plysse). Außerdem enthält pyparsing mehrere Beispiele von Abfrageparsern auf der Seite [Examples] (http://pyparsing.wikispaces.com/Examples). – PaulMcG

Antwort

1

Die wirkliche Frage ist, wie komplex Ihre zusammengesetzten Aussagen werden, und gehen sie nur um UND- und ODER-Schlüsselwörter einzuschließen. Von dem, was ich sagen kann, ist es besser, eine richtige Grammatik dafür zu definieren, als nur eine Mischung aus regulären Ausdrücken zu benutzen, um den Job zu erledigen (obwohl das im Grunde eine Grammatik ist).

Ich würde vorschlagen, mit Parsely, wo Sie eine Grammatik im Lex-Format klar definieren können und einen Parser für Sie generiert haben. Auf diese Weise können Sie beim Debuggen die Dinge besser in Token bringen und besser verstehen.

+0

verwendet. Nun möchte ich sogar große Abfragen mit vielen Bedingungen für ein Feld betrachten. natürlich gibt es Einschränkungen, wie gemischte Typen für ein bestimmtes Feld nicht zu verwenden (wie <9 und == "etwas", aber diese Datentypprüfung würde nach dem eigentlichen Parsing kommen.). Die meisten Abfragen verwenden und, oder, nicht, nicht gleich und nicht. Würde Petersilie überprüfen und zu dir zurückkommen –

+0

Petersilie hat die meisten Jobs erledigt. Danke –

+0

Heyy, wenn du könntest, könntest du einen Blick auf diese http://stackoverflow.com/questions/37187918/regex-parse-error-by-parsley-python werfen –

1

Sicher. Hier ist ein Beispiel, das nur JSON verwendet.

Für eine grundlegende Abfrage Einfeld, verwenden Sie eine Zuordnung:

{"fieldname": {"op": "=", "value": "somevalue"}} 

Für eine Verbindung Abfrage, so etwas wie:

{"and": [ 
    {"field": {"op": "=", "value": "somevalue"}}, 
    {"field2": {"op": ">", "value": 9.22}}, 
    ]} 

Für eine komplexe Abfrage, wie in Ihrem Beispiel:

{ 
    "and": [ 
    { 
     "index": { 
     "op": "=", 
     "value": "name" 
     } 
    }, 
    { 
     "schema": { 
     "op": "=", 
     "value": "name" 
     } 
    }, 
    { 
     "or": [ 
     { 
      "field1": { 
      "op": "=", 
      "value": "name1" 
      } 
     }, 
     { 
      "field1": { 
      "op": "=", 
      "value": "name2" 
      } 
     } 
     ] 
    }, 
    { 
     "or": [ 
     { 
      "field2": { 
      "op": "<", 
      "value": 9.22 
      } 
     }, 
     { 
      "field2": { 
      "op": ">=", 
      "value": 2.32 
      } 
     } 
     ] 
    }, 
    { 
     "or": [ 
     { 
      "or": [ 
      { 
       "field3": { 
       "op": "<", 
       "value": 9.22 
       } 
      }, 
      { 
       "field3": { 
       "op": ">=", 
       "value": 2.32 
       } 
      } 
      ] 
     }, 
     { 
      "or": [ 
      { 
       "field3": { 
       "op": "<", 
       "value": 100 
       } 
      }, 
      { 
       "field3": { 
       "op": ">", 
       "value": 90 
       } 
      } 
      ] 
     } 
     ] 
    } 
    ] 
} 
+1

Obwohl dies sinnvoll ist, wenn er die Anfragen tatsächlich schreibt, wird es ein Albtraum. Es ist besser, einfach einen Parser für die Abfragesprache im Backend zu haben, um die Oberfläche zu vereinfachen. –

+0

Ich denke nicht, dass dies ein Alptraum wäre, es sei denn, Sie machen regelmäßig große zusammengesetzte Abfragen von Hand und unterscheiden sich nicht wesentlich von vielen existierenden Lösungen (die Struktur ist fast identisch mit der von LDAP-Filter-Strings) strukturiert, zum Beispiel). – larsks

+0

Der Ansatz ist der einfachste Weg, den ich auf der Entwicklerseite machen könnte. Aber wie Brainiac sagte, es wäre wirklich schwer für Menschen, solche komplexen Fragen zu stellen. (<9.22 and > = 2.32) oder (<100 and > 90), Das ist noch keine wirklich große komplexe Aussage, es hat so viele Charaktere aufgegriffen.Ich denke, es wäre besser, wenn ein Endbenutzer eine Art von Abfragesprache für dieses –

Verwandte Themen