I'm struggling with a problem related to using partial_fields and nested data. The examples below are a simplification of my actual problem but are enough I hope to demonstrate it.
Say I'm building a CMS and it supports multiple languages. In the editor for this CMS I'd like to show all the content the user can access and this access is restricted by the locales they can see and whether a particular piece of content has been set as visible yet.
Below are two ways I tried unsuccessfully to map this. Am I going to need to use parent/child documents?
curl -XDELETE 'http://localhost:9201/test_cms'
curl -XPUT 'http://localhost:9201/test_cms'
curl -XPUT 'http://localhost:9201/test_cms/document/_mapping' -d '{
"document" : {
"properties": {
"name": { "type": "string" },
"content": {
"type": "nested",
"properties": {
"locale": { "type": "string" },
"visible": { "type": "boolean" },
"data": { "type": "string" }
}
}
}
}
}'
curl -XPUT 'http://localhost:9201/test_cms/document/1' -d '{
"name": "Some Name",
"content": [
{
"locale": "en",
"visible": true,
"data": "Some english content"
},
{
"locale": "es",
"visible": true,
"data": "Some spanish content"
},
{
"locale": "fr",
"visible": false,
"data": "Some french content"
}
]
}'
curl -XPUT 'http://localhost:9201/test_cms/document/2' -d '{
"name": "Some Other Name",
"content": [
{
"locale": "en",
"visible": true,
"data": "Some other english content"
},
{
"locale": "es",
"visible": true,
"data": "Some other spanish content"
},
{
"locale": "fr",
"visible": true,
"data": "Some other french content"
}
]
}'
curl -XGET 'http://localhost:9201/test_cms/_search?pretty=true' -d '{
"query": {
"nested": {
"path": "content",
"query": {
"filtered": {
"filter": {
"bool" : {
"must" : [
{ "term": { "visible": true }},
{ "terms": { "locale": ["en", "fr"] }}
]
}
},
"query": {
"query_string": {
"fields": [
"data"
],
"query": "other"
}
}
}
}
}
}
}'How can I remove a nested content based on locale or visibility or not having content matching the search? The output is:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.8465736,
"hits" : [ {
"_index" : "test_cms",
"_type" : "document",
"_id" : "2",
"_score" : 0.8465736, "_source" : {
"name": "Some Other Name",
"content": [
{
"locale": "en",
"visible": true,
"data": "Some other english content"
},
{
"locale": "es",
"visible": true,
"data": "Some other spanish content"
},
{
"locale": "fr",
"visible": true,
"data": "Some other french content"
}
]
}
} ]
}
}In this case I'd like it to be
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.8465736,
"hits" : [ {
"_index" : "test_cms",
"_type" : "document",
"_id" : "2",
"_score" : 0.8465736, "_source" : {
"name": "Some Other Name",
"content": [
{
"locale": "en",
"visible": true,
"data": "Some other english content"
},
{
"locale": "fr",
"visible": true,
"data": "Some other french content"
}
]
}
} ]
}
}I.e. the spanish locale removed as it wasn't included in the filter
If I arrange the data as below I can use partial_fields but only for the locale, I can't specify visible for example. Also I have to list out the fields explicitly in the query
curl -XDELETE 'http://localhost:9201/test_cms'
curl -XPUT 'http://localhost:9201/test_cms'
curl -XPUT 'http://localhost:9201/test_cms/document/_mapping' -d '{
"document" : {
"properties": {
"name": { "type": "string" },
"content": { "type": "nested" }
},
"dynamic_templates" : [
{
"visibility_template" : {
"path_match": "content.*.visible",
"mapping": { "type": "boolean" }
}
},
{
"data_template" : {
"path_match": "content.*.data",
"mapping": { "type": "string" }
}
}
]
}
}'
curl -XPUT 'http://localhost:9201/test_cms/document/1' -d '{
"name": "Some Name",
"content": [
{
"en" : {
"visible": true,
"data": "Some en content"
}
},
{
"es" : {
"visible": true,
"data": "Some es content"
}
},
{
"fr" : {
"visible": false,
"data": "Some fr content"
}
}
]
}'
curl -XPUT 'http://localhost:9201/test_cms/document/2' -d '{
"name": "Some Other Name",
"content": [
{
"en" : {
"visible": true,
"data": "Some other en content"
}
},
{
"es" : {
"visible": true,
"data": "Some other es content"
}
},
{
"fr" : {
"visible": true,
"data": "Some other fr content"
}
}
]
}'
curl -XGET 'http://localhost:9201/test_cms/_search?pretty=true' -d '{
"partial_fields" : {
"partial" : { "exclude": ["content.es"] }
},
"query" : {
"nested" : {
"path": "content",
"query": {
"query_string" : {
"fields": ["content.en.data", "content.fr.data"],
"query": "other"
}
}
}
}
}
}'