2016-04-27 14 views
3

私は弾性検索のような検索サーバーで作業しています。私が開発しているちょっとしたプロジェクトです。ほとんどの部品を完成させましたが、ユーザーがシステムとやりとりする方法にはまっています。Pythonを使用してクエリ言語を作成

私は最初、ユーザーが必須フィールドとその値を含むJSONクエリを送信することによってリクエストすることを決定しました。しかし、私が直面している問題は、jsonの方法でクエリを評価することはできますが、ブールクエリとCompounfステートメントを実装することはできません。実際に作成せずに、これを実現するために、やや簡単な方法はあり

は私が

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

ような何かをしようとしていたが、ブール式が

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. 

を実装されている場合、それはまた、このような何かをすることができクエリ言語文法。もしそうなら、私はそれをどのように達成するかもしれません。

私は各フィールドの値に基づいて値を分割することを考えていましたが、複合文がある場合は機能しません。

私も同様にpyparsingをチェックしていましたが、私はそれを使用する作業方法を理解できませんでした。

+0

[whoosh](https://bitbucket.org/mchaput/whoosh/wiki/Home)または[plyse](https://github.com/sebastiandev/plyse)をご覧ください。また、pyparsingには、[Example](http://pyparsing.wikispaces.com/Examples)ページのクエリパーサーのサンプルがいくつか含まれています。 – PaulMcG

答えて

1

本物の質問は、あなたの複合ステートメントがどのくらい複雑になるのか、そして彼らは唯一のものですかANDキーワードとORキーワードを含める。私は、文法が本質的であるとはいえ、これを行うには正規表現の組み合わせを使うよりも、適切な文法を定義するほうが良いということです。

lex形式の文法を明確に定義し、パーサを生成することができるparselyを使用することをお勧めします。こうすることで、デバッグしているときに物事をより良くトークン化し、理解を深めることができます。

+0

フィールドの条件が多い大きなクエリについても検討したいと思います。もちろん、<9と== "something"のような特定のフィールドに混合データ型を使用しないような制限がありますが、このデータ型チェックは実際に解析した後に行われます。ほとんどのクエリは、and、or、not、equalではなく、notを使用します。パセリをチェックして、あなたに戻ってくる –

+0

パーズリーはほとんどの仕事をしました。ありがとう、 –

+0

可能であれば、これを見てみるといいですかhttp://stackoverflow.com/questions/37187918/regex-parse-error-by-parsley-python –

1

ここではJSONだけを使用する例を示します。あなたの例のように、複雑なクエリの場合

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

:ような何かを、複合クエリの場合

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

:基本的な単一フィールドのクエリのために

は、マッピングを使用

{ 
    "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

これは理にかなっていますが、彼が実際にクエリを書くとき、それは悪夢になるでしょう。インターフェイスを簡単にするために、バックエンドにクエリ言語パーサーを置くことをお勧めします。 –

+0

大規模な複合クエリを手作業で作成していない限り、これは扱いにくいと思うことはほとんどありませんし、既存の多くのソリューションとは実質的に異なるわけでもありません(LDAPフィルタ文字列の構造例えば、構造化された)。 – larsks

+0

アプローチは、私が開発者側で行うことができる最も簡単な方法です。しかし、頭の中の人のように、人々がそのような複雑な質問をすることは本当に難しいでしょう。 (<9.22 and > = 2.32)または(<100 and > 90)、これはまだまだ複雑な文ではありません。エンドユーザーがこれに何らかの種類のクエリ言語を使用する方が良いと思います。 –

関連する問題