次のシナリオでインデックスをクエリする方法。
ドキュメントには次の属性があります。
body: # text
shares: # array of share(s)
share:
orgid: # text
role: # text
いくつかのサンプル ドキュメントを次に示します。
docs = [
{'body':'hello', 'shares':[{'orgid':'abc.de.1', 'role':'11'},
{'orgid':'abc', 'role':'1'}]},
{'body':'world', 'shares':[{'orgid':'abc.de', 'role':'111'}]},
{'body':'today', 'shares':[{'orgid':'abc', 'role':'111'}]}
]
ElasticSearch 構文を使用して、次のクエリを実行したいと考えています。
Give me all docs where prefix of 'shares.orgid' = 'abc' and prefix of shares.role = '11'
Should return: all of them
Give me all docs where prefix of 'shares.orgid' = 'abc.de' and prefix of shares.role = '111'
Should return: world
Give me all docs where prefix of 'shares.orgid' = 'abc.de.1' and prefix of shares.role = '11'
Should return: nothing
Give me all docs where prefix of 'shares.orgid' = 'abc' and prefix of shares.role = '111'
Should return: world, today
これについて調べていると、次の興味深い情報が見つかりました。
特に :
ElasticSearch では、has_children クエリと top_children クエリの 2 種類のクエリを使用して、子ドキュメントを操作できます。最初のクエリは、ElasticSearch Query DSL で表現されたクエリと子の型を受け入れ、指定されたクエリに一致する子を持つすべての親ドキュメントを返します。2 番目のタイプのクエリは、設定された数の子ドキュメントに対して実行され、親ドキュメントに集約されます。2 番目のクエリ タイプのスコア計算を選択することもできます。
また興味深い: http://www.elasticsearch.org/guide/reference/query-dsl/has-child-query.html
再インデックスの詳細: http://www.elasticsearch.org/guide/reference/api/index_.html 親と子
子ドキュメントは、インデックスを作成するときにその親を指定することでインデックスを作成できます。例えば:
$ curl -XPUT localhost:9200/blogs/blog_tag/1122?parent=1111 -d '{
"tag" : "something"
}'
子ドキュメントをインデックス化する場合、ルーティング パラメーターを使用してルーティング値が明示的に指定されていない限り、ルーティング値はその親と同じになるように自動的に設定されます。
編集:
私は近づいています。これは、私が試しているラッパーを使用したテストで、アプローチを示しています。質問/問題の解決策を示すテストを書きます。https://github.com/aparo/pyes/blob/master/tests/test_nested.py . 私はそのテストを実行し、PrefixQuery を使用するように微調整したところ、動作しました。
コメント投稿者の javana によると、子クエリは進むべき方向ではありません。pyes を使用した抜粋の例を次に示します。
from pyes.filters import TermFilter, NestedFilter
from pyes.query import FilteredQuery, MatchAllQuery, BoolQuery, TermQuery, PrefixQuery
# from their unit test setup
self.conn.index({"field1": "value1",
"nested1": [{"n_field1": "n_value1_1",
"n_field2": "n_value2_1"},
{"n_field1": "n_value1_2",
"n_field2": "n_value2_2"}]},
self.index_name, self.document_type, 1)
self.conn.index({"field1": "value1",
"nested1": [{"n_field1": "n_value1_1",
"n_field2": "n_value2_2"},
{"n_field1": "n_value1_2",
"n_field2": "n_value2_1"}]},
self.index_name, self.document_type, 2)
self.conn.index({"field1": "value1",
"nested1": [{"n_field1": "ni",
"n_field2": "11"},
{"n_field1": "n_value1_2",
"n_field2": "n_value2_1"}]},
self.index_name, self.document_type, 3)
self.conn.index({"field1": "value1",
"nested1": [{"n_field1": "ni.kirmse.104",
"n_field2": "111"},
{"n_field1": "n_value1_2",
"n_field2": "n_value2_1"}]},
self.index_name, self.document_type, 4)
self.conn.refresh(self.index_name)
# just hacked their test to quickly see if I could do a prefix query on beginning of nested array/list values.
q = FilteredQuery(MatchAllQuery(),
NestedFilter('nested1',
BoolQuery(must=[PrefixQuery('nested1.n_field1', 'ni'),
PrefixQuery('nested1.n_field2', '111')])))
resultset = self.conn.search(query=q, indices=self.index_name, doc_types=[self.document_type])