2017-07-19 3 views
1

ユーザーは入力を提供してデータベースにクエリを送信できる単純なWebページがあります。現在、mongodbを使用していますが、クエリが高速であるため、elasticsearchに移行したいと考えています。elasticsearch:最初に実行するクエリを指定します。

開始日や終了日などの必須の検索フィールドと、エントリに一致する検索文字列や親エントリに一致するような親検索文字列などのオプションフィールドがあります。親子関係は、各エントリの祖先IDを含むフィールドを介して記述されます。

質問は次のとおりです。検索文字列と親検索文字列の両方が提供されている場合、クエリを実行する前に知っておくべき方法がありますか?

たとえば、特定の親検索では2つのdocs/parentエントリしか得られず、検索文字列に一致するすべての子を取得できます。その場合、最初に親クエリを実行してからエントリクエリを実行する必要があります。

1つのオプションは、両方のクエリのカウントを取得してから、最初に最も小さいものを実行することですが、このソリューションは悪いです。なぜなら、クエリは2回実行されるからです。カウントのために1回、実際のクエリに対して1回。

これを解決する他のオプションはありますか?

PS。私たちは、

があるユーザーは、次のフィールドに一致するすべてのエントリを検索したいとしましょう

elasticsearch V1.7を使用しています。

するsearchString:type:BLOCK AND name:test

parentSearchString:name:parentTest AND NOT type:BLOCK

これは、私たちのどちらかが

  1. parentSearchStringに一致するすべてのエントリ(親)を取得し、そのIDを格納していることを意味します。次に、searchStringに一致するすべてのエントリを取得し、ancestorsフィールドに親IDのいずれかを含める必要があります。

OR

  • searchStringに一致するすべてのエントリをフェッチし、すべてancestors IDを格納します。次に、parentSearchStringに一致するすべてのエントリを取得し、そのIDはancestorsのいずれかです。
  • 親と子の両方のエントリは同じ構造であり、同じインデックスに存在します。親子関係が10回ネストされているため、異なるインデックスを持つことはできません。そのため、エントリは親と子の両方になる可能性があります。エントリは、多かれ少なかれのようになります。すべての

    { 
        id: "e32452365321", 
        name: "name", 
        type: "type", 
        ancestors: "id1 id2 id3" // stored in node as an array of ids 
    } 
    

    答えて

    0

    まず、可能な場合、私は、あなたのElasticsearchのバージョンをアップグレードするために、あなたに助言します。 1.7以降、多くのことが起こりました。正直言って、次の記事に書かれている内容のすべてがこのような古いバージョンで有効であるかどうかはわかりません(たぶんそうではありません)。

    あなたの実際の質問に:うまくいけば私はあなたを正しく理解していますが、Elasticsearchのクエリがどれほどコストがかかるかを推測しようとしますか?まあ、する必要はありません。 1つのネストされたクエリにすべてのクエリを指定すると、Elasticsearchはそれを行います。https://www.elastic.co/blog/elasticsearch-query-execution-order

    速度に関しては、計算のスコアに時間がかかります。したがって、ソートがelasticsearch _scoreに基づいていない場合は、ブール値のフィルタクエリを使用します。これは親マッチの_scoreだけでソートする場合にも適用されます。子供のクエリをフィルタに入れることができます。あなたの例に


    更新

    おかげで、私は今の問題を参照してください。自己参照の親子関係は残念ながらElasticSearchのnot supportedですので、あなたのアプローチは正しいでしょう。 application-joinsについては、ドキュメントの短い章を参照してください。

    一般的に、可能な限り少ない数のID /用語で2番目のクエリを送信したいとします。両方のクエリのカウントを取得するのは、考えられるほど悪くはありませんが、結果はまだキャッシュされている可能性が高いため、実際に役立ちますか?子供から親に行く場合は、実際の文書数ではなく、祖先(フィールド値)を数えなければならないからです。

    私は、最も高価な操作は非常に頻繁にディスクから結果のソースをフェッチしていると言います。どのような方法で行っても、最初のクエリで必要なものだけを取得する必要があります。だからあなたのオプションは次のとおりです。

    • は、親の試合の唯一のIDを取得し、2番目のクエリでancestorsterms filterを使用しています。
    • または、子の一致の祖先フィールドのみを取り出し、2番目のクエリでid filterを使用します。

    残念ながら、私はこれらのアプローチのスピードを比較するのに十分な経験がないため、残念なことに、それ以上にお手伝いできません。私の推測では、IDフィルタは一般的に高速かもしれません。しかし、それはちょうど推測です...

    +0

    私たちは弾力性を更新するのは簡単ではないので、今はそのために作業しなければなりません。私もあなたをよく理解していれば、1つのネストされたクエリで両方のクエリを持つことはできないと思っています。たとえば、親クエリを最初に実行した場合、子クエリは親IDのフィルタを持つ必要があります。そして、私はどこかでこれが現在弾性で利用できないと読んでいます – XeniaSis

    +0

    私はあなたの検索をかなり理解していないようです。多分あなたのオープニングポストで簡単な例を提供できますか?たぶん、SQLで表現する方が簡単なのであれば。私はそれに応じて私の答えを更新しようとします。あなたの検索があまり複雑ではない(単純なウェブページを持っているので、私はこれを仮定しています)、私はまだそれが1つのクエリ内で実行できると思います。 – Slomo

    +0

    小さな例を追加しました – XeniaSis

    関連する問題