Ответ 1
Важное различие между elasticsearch и реляционными базами данных состоит в том, что elasticsearch не может выполнять объединения. В elasticsearch вы всегда ищете один индекс или объединение индексов. Но в случае отношений родителя/ребенка можно ограничить результаты в родительском индексе, используя запрос для дочернего индекса. Например, этот запрос можно выполнить в типе account
.
{
"bool": {
"must": [
{
"text" : { "name": "foo" }
}, {
"term" : { "state": "active" }
}, {
"has_child": {
"type": "email",
"query": {
"text": {"email": "bar" }
}
}
}
]
}
}
Этот запрос вернет вам только родительский документ (дочерние документы не будут возвращены). Вы можете использовать родительский идентификатор, возвращаемый этим запросом, чтобы найти всех дочерних элементов этого родителя, используя поле _parent
, которое по умолчанию сохраняется и индексируется.
{
"term" : { "_parent": "1" }
}
Или вы можете ограничить свои результаты только для детей, которые содержат слово bar
в поле email
:
{
"bool": {
"must": [
{
"term" : { "_parent": "1" }
}, {
"text" : { "email": "bar" }
}
]
}
}
Я не думаю, что можно указать родителя в 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