我正在阅读elasticsearch的文档,此[page] [1]讨论了使用将孩子映射到父类型_parent。
_parent
如果我有被称为孩子的email父母,则被称为account:
email
account
每种类型的字段:
account (http://localhost:9200/myapp/account/1) ======== id name some_other_info state email (http://localhost:9200/myapp/email/1?parent=1) ======== id email
我怎么能在搜索name领域account和email领域的email前提是state的account是active?
name
state
active
有没有办法让父母拥有的所有孩子(某种类型或任何类型)?
在索引子文档时,是否可以将父对象作为对象属性传递给JSON数据,而不是将其作为查询字符串的一部分?
在尝试了imotov的建议之后,我想到了以下查询:
这是在执行 http://localhost:9200/myapp/account/_search
http://localhost:9200/myapp/account/_search
{ "query": { "bool": { "must": [ { "prefix": { "name": "a" } }, { "term": { "statuses": "active" } } ], "should": [ { "has_child": { "type": "emailaddress", "query": { "prefix": { "email": "a" } } } } ] } } }
问题是上述内容没有给我提供电子邮件匹配的任何帐户。
我想要的效果本质上是这样的:
emailaddress
accounts
因此,我基本上需要能够OR在2种类型之间进行搜索并返回匹配项的父类型。
OR
测试数据:
curl -XPUT http://localhost:9200/test/account/1 -d '{ "name": "John Smith", "statuses": "active" }' curl -XPUT http://localhost:9200/test/account/2 -d '{ "name": "Peter Smith", "statuses": "active" }' curl -XPUT http://localhost:9200/test/account/3 -d '{ "name": "Andy Smith", "statuses": "active" }' //Set up mapping for parent/child relationship curl -XPUT 'http://localhost:9200/test/email/_mapping' -d '{ "emails" : { "_parent" : {"type" : "account"} } }' curl -XPUT http://localhost:9200/test/email/1?parent=1 -d '{ "email": "john@smith.com" }' curl -XPUT http://localhost:9200/test/email/2?parent=1 -d '{ "email": "admin@mycompany.com" }' curl -XPUT http://localhost:9200/test/email/3?parent=1 -d '{ "email": "abcd@efg.com" }' curl -XPUT http://localhost:9200/test/email/4?parent=2 -d '{ "email": "peter@peter.com" }' curl -XPUT http://localhost:9200/test/email/5?parent=3 -d '{ "email": "andy@yahoo.com" }' curl -XPUT http://localhost:9200/test/email/6?parent=3 -d '{ "email": "support@mycompany.com" }'
imotov的解决方案为我工作。我已经找到另一种方法是查询accountS代表status = active,然后运行bool的结果,并使用过滤器has_child对孩子的类型和prefix在name内部bool过滤器。
status = active
bool
has_child
prefix
elasticsearch和关系数据库之间的重要区别是elasticsearch无法执行联接。在elasticsearch中,您始终在搜索单个索引或索引并集。但是在父/子关系的情况下,可以使用对子索引的查询来限制父索引中的结果。例如,您可以对account类型执行此查询。
{ "bool": { "must": [ { "text" : { "name": "foo" } }, { "term" : { "state": "active" } }, { "has_child": { "type": "email", "query": { "text": {"email": "bar" } } } } ] } }
该查询将仅返回父文档(不返回子文档)。您可以使用此查询返回的父代ID,使用field来查找该父代的所有子代,_parent默认情况下,该字段已存储并建立索引。
{ "term" : { "_parent": "1" } }
或者,您可以将结果只限于包含bar该字段中单词的子级email:
bar
{ "bool": { "must": [ { "term" : { "_parent": "1" } }, { "text" : { "email": "bar" } } ] } }
我认为除非您使用_bulk indexing,否则无法在json中指定parent 。
这是使用问题中提供的测试数据可以实现电子邮件查找的方式:
#!/bin/sh curl -XDELETE 'http://localhost:9200/test' && echo curl -XPOST 'http://localhost:9200/test' -d '{ "settings" : { "number_of_shards" : 1, "number_of_replicas" : 0 }, "mappings" : { "account" : { "_source" : { "enabled" : true }, "properties" : { "name": { "type": "string", "analyzer": "standard" }, "statuses": { "type": "string", "index": "not_analyzed" } } }, "email" : { "_parent" : { "type" : "account" }, "properties" : { "email": { "type": "string", "analyzer": "standard" } } } } }' && echo curl -XPUT 'http://localhost:9200/test/account/1' -d '{ "name": "John Smith", "statuses": "active" }' curl -XPUT 'http://localhost:9200/test/account/2' -d '{ "name": "Peter Smith", "statuses": "active" }' curl -XPUT 'http://localhost:9200/test/account/3' -d '{ "name": "Andy Smith", "statuses": "active" }' //Set up mapping for parent/child relationship curl -XPUT 'http://localhost:9200/test/email/1?parent=1' -d '{ "email": "john@smith.com" }' curl -XPUT 'http://localhost:9200/test/email/2?parent=1' -d '{ "email": "admin@mycompany.com" }' curl -XPUT 'http://localhost:9200/test/email/3?parent=1' -d '{ "email": "abcd@efg.com" }' curl -XPUT 'http://localhost:9200/test/email/4?parent=2' -d '{ "email": "peter@peter.com" }' curl -XPUT 'http://localhost:9200/test/email/5?parent=3' -d '{ "email": "andy@yahoo.com" }' curl -XPUT 'http://localhost:9200/test/email/6?parent=3' -d '{ "email": "support@mycompany.com" }' curl -XPOST 'http://localhost:9200/test/_refresh' echo curl 'http://localhost:9200/test/account/_search' -d '{ "query": { "bool": { "must": [ { "term": { "statuses": "active" } } ], "should": [ { "prefix": { "name": "a" } }, { "has_child": { "type": "email", "query": { "prefix": { "email": "a" } } } } ], "minimum_number_should_match" : 1 } } }' && echo