私はelasticsearchのドキュメントを読んでおり、この[page] [1]では、_parent
を使用して子を親タイプにマッピングする方法について説明しています。
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
フィールドを検索するにはどうすればよいですか?
親が所有する(特定のタイプまたは任意のタイプの)すべての子を取得する方法はありますか?
子ドキュメントのインデックスを作成するときに、クエリ文字列の一部ではなく、JSONデータのオブジェクトプロパティとして親を渡すことはできますか?
Imotovの提案を試した後、私はこのクエリを思いつきました:
これはhttp://localhost:9200/myapp/account/_search
で実行されます
{
"query": {
"bool": {
"must": [
{
"prefix": {
"name": "a"
}
},
{
"term": {
"statuses": "active"
}
}
],
"should": [
{
"has_child": {
"type": "emailaddress",
"query": {
"prefix": {
"email": "a"
}
}
}
}
]
}
}
}
問題は、上記ではメールが一致するアカウントが得られないことです。
私が望む効果は本質的にこれです:
account
またはemailaddress
タイプの名前と照合されます。accounts
が一致した場合は、それらを返すだけです。 emailaddress
が一致した場合は、その親アカウントを返します。したがって、基本的に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": "[email protected]"
}'
curl -XPUT http://localhost:9200/test/email/2?parent=1 -d '{
"email": "[email protected]"
}'
curl -XPUT http://localhost:9200/test/email/3?parent=1 -d '{
"email": "[email protected]"
}'
curl -XPUT http://localhost:9200/test/email/4?parent=2 -d '{
"email": "[email protected]"
}'
curl -XPUT http://localhost:9200/test/email/5?parent=3 -d '{
"email": "[email protected]"
}'
curl -XPUT http://localhost:9200/test/email/6?parent=3 -d '{
"email": "[email protected]"
}'
imotovのソリューションは私のために働いた。私が見つけた別の解決策は、account
sにstatus = active
を照会し、結果に対してbool
フィルターを実行し、子タイプにhas_child
を使用し、prefix
フィルター内のname
にbool
を使用することです。
Elasticsearchとリレーショナルデータベースの重要な違いは、elasticsearchは結合を実行できないことです。 Elasticsearchでは、常に単一のインデックスまたはインデックスの和集合を検索しています。ただし、親子関係の場合は、子インデックスのクエリを使用して、親インデックスの結果を制限することができます。たとえば、このクエリはaccount
タイプで実行できます。
{
"bool": {
"must": [
{
"text" : { "name": "foo" }
}, {
"term" : { "state": "active" }
}, {
"has_child": {
"type": "email",
"query": {
"text": {"email": "bar" }
}
}
}
]
}
}
このクエリは親ドキュメントのみを返します(子ドキュメントは返されません)。このクエリによって返された親IDを使用して、デフォルトで保存およびインデックス付けされるフィールド_parent
を使用して、この親のすべての子を検索できます。
{
"term" : { "_parent": "1" }
}
または、フィールドbar
に単語email
を含む子のみに結果を制限することもできます。
{
"bool": {
"must": [
{
"term" : { "_parent": "1" }
}, {
"text" : { "email": "bar" }
}
]
}
}
_ bulk indexing を使用していない限り、jsonで親を指定することはできないと思います。
これは、質問で提供されたテストデータを使用して電子メールルックアップを実装する方法です。
#!/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": "[email protected]"
}'
curl -XPUT 'http://localhost:9200/test/email/2?parent=1' -d '{
"email": "[email protected]"
}'
curl -XPUT 'http://localhost:9200/test/email/3?parent=1' -d '{
"email": "[email protected]"
}'
curl -XPUT 'http://localhost:9200/test/email/4?parent=2' -d '{
"email": "[email protected]"
}'
curl -XPUT 'http://localhost:9200/test/email/5?parent=3' -d '{
"email": "[email protected]"
}'
curl -XPUT 'http://localhost:9200/test/email/6?parent=3' -d '{
"email": "[email protected]"
}'
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