こちらのNested datatypeでお望みの挙動になるのではないでしょうか。
https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html
こちらで、Mappingの変更、クエリを変更して試した内容を書いておきますので
期待する内容となっているか確認してみてください。
なお、確認にはkibanaのDev ToolsのConsoleを使っています。
Mappingの変更
valueのtypeをobjectからnestedに変更します。
PUT forum1019
{
"mappings": {
"testtype": {
"properties": {
"name": {
"type": "keyword"
},
"value": {
"type": "nested"
}
}
}
}
}
データの作成
前と変更なし
POST forum1019/testtype/5
{
"name": "TEST",
"value": [
{
"string": "one",
"class": "A"
},
{
"string": "two",
"class": "B"
},
{
"string": "three",
"class": "B"
},
{
"string": "four",
"class": "C"
}
]
}
クエリの変更
nestedを使ったクエリに変更します。
(_sourceをfalseにしているのは、便宜的に結果を見やすくするためです)
inner_hitsをつけておくことで、ヒットした部分だけが抽出されます。
GET forum1019/_search
{
"_source": false,
"query": {
"nested": {
"path": "value",
"query": {
"bool": {
"must": [
{
"match": {
"value.class": "B"
}
}
]
}
},
"inner_hits": {}
}
}
}
結果
inner_hists内を見てください。twoとthreeしか返されていないことが確認できました。
{
"took": 14,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.6931472,
"hits": [
{
"_index": "forum1019",
"_type": "testtype",
"_id": "5",
"_score": 0.6931472,
"inner_hits": {
"value": {
"hits": {
"total": 2,
"max_score": 0.6931472,
"hits": [
{
"_nested": {
"field": "value",
"offset": 2
},
"_score": 0.6931472,
"_source": {
"value": {
"string": "three",
"class": "B"
}
}
},
{
"_nested": {
"field": "value",
"offset": 1
},
"_score": 0.6931472,
"_source": {
"value": {
"string": "two",
"class": "B"
}
}
}
]
}
}
}
}
]
}
}