[英]How to express an unusual query using ElasticSearch and/or Apache Solr?
在以下情況下如何查詢索引。
文檔具有以下屬性:
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
ElasticSearch使您可以使用兩種類型的查詢– has_children和top_children查詢對子文檔進行操作。 第一個查詢接受以ElasticSearch Query DSL表示的查詢以及子類型,它會導致所有子文檔與給定查詢匹配的父文檔。 第二類查詢針對一定數量的子文檔運行,然后將它們匯總到父文檔中。 我們還可以為第二種查詢類型選擇得分計算。
同樣感興趣的是: 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"
}'
為子文檔建立索引時,除非使用routing參數明確指定了路由值,否則路由值將自動設置為與父文檔相同。
編輯:
我越來越近了。 這是一個我嘗試使用包裝器的測試,演示了一種方法。 我將編寫一個測試來演示該問題的解決方案。 https://github.com/aparo/pyes/blob/master/tests/test_nested.py 我運行了該測試,並對其進行了調整以使用PrefixQuery,它可以工作。
對於每個評論者javanna,子查詢都不是前進的方向。 這是使用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])
好的,我找到了使用pyes(一種Python的Elasticsearch包裝器)來執行此操作的方法。
我在這里獲取了他們的測試之一: https : //github.com/aparo/pyes/blob/master/tests/test_nested.py
為了回答這個問題,我修改了測試以演示如何實現目標。
class NestedSearchTestCase(ESTestCase):
def setUp(self):
super(NestedSearchTestCase, self).setUp()
mapping = {
'shares': {
'type': 'nested'
}
}
self.conn.create_index(self.index_name)
self.conn.put_mapping(self.document_type, {'properties': mapping}, self.index_name)
self.conn.index({"body": "hello",
"shares": [{"orgid": "abc.de.1",
"role": "11"},
{"orgid": "abc",
"role": "1"}]},
self.index_name, self.document_type, 1)
self.conn.index({"body": "world",
"shares": [{"orgid": "abc.de",
"role": "111"}]},
self.index_name, self.document_type, 2)
self.conn.index({"body": "today",
"shares": [{"orgid": "abc",
"role": "111"}]},
self.index_name, self.document_type, 3)
self.conn.refresh(self.index_name)
def test_nested_filter(self):
q = FilteredQuery(MatchAllQuery(),
NestedFilter('shares',
BoolQuery(must=[PrefixQuery('shares.orgid', 'abc'),
PrefixQuery('shares.role', '11')])))
resultset = self.conn.search(query=q, indices=self.index_name, doc_types=[self.document_type])
self.assertEquals(resultset.total, 3)
# prints: hello, world, today
print ', '.join([r['body'] for r in resultset])
q = FilteredQuery(MatchAllQuery(),
NestedFilter('shares',
BoolQuery(must=[PrefixQuery('shares.orgid', 'abc.de'),
PrefixQuery('shares.role', '111')])))
resultset = self.conn.search(query=q, indices=self.index_name, doc_types=[self.document_type])
self.assertEquals(resultset.total, 1)
# prints: world
print ', '.join([r['body'] for r in resultset])
q = FilteredQuery(MatchAllQuery(),
NestedFilter('shares',
BoolQuery(must=[PrefixQuery('shares.orgid', 'abc.de.1'),
PrefixQuery('shares.role', '11')])))
resultset = self.conn.search(query=q, indices=self.index_name, doc_types=[self.document_type])
self.assertEquals(resultset.total, 0)
# prints: nothing
print ', '.join([r['body'] for r in resultset])
q = FilteredQuery(MatchAllQuery(),
NestedFilter('shares',
BoolQuery(must=[PrefixQuery('shares.orgid', 'abc'),
PrefixQuery('shares.role', '111')])))
resultset = self.conn.search(query=q, indices=self.index_name, doc_types=[self.document_type])
self.assertEquals(resultset.total, 2)
# prints: world, today
print ', '.join([r['body'] for r in resultset])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.