Mustache double quotes problem in search templates

What is the best way to use mustache False values feature in Elasticsearch template?

At the moment I am trying to select function based on boolean value.
Rendering seems to be working according to the logic, but it prints empty double quotes and I cannot get rid of those.

Code example:
Template snippet:

                    "must": {
                        "function_score": {
                            "functions": [
                                "{{^isLocationFunctionNeeded}}",
                                {
                                    "exp": {
                                        "location": {
                                            "origin": {
                                                "lat": "0.0",
                                                "lon": "0.0"
                                            },
                                            "offset": "1km",
                                            "scale": "50km"
                                        }
                                    }
                                },
                                "{{/isLocationFunctionNeeded}}",
                                {
                                    "random_score": {},
                                    "weight": 0.00001
                                }
                            ],
                            "score_mode": "sum"
                        }
                    }

Render snippet:

 "must": {
                "function_score": {
                    "functions": [
                        "",
                        {
                            "random_score": {},
                            "weight": 1.0E-5
                        }
                    ],
                    "score_mode": "sum"
                }
            }

Error I get trying to run the template on ELK:

    "error": {
        "root_cause": [
            {
                "type": "parsing_exception",
                "reason": "failed to parse [START_OBJECT]. malformed query, expected a [VALUE_STRING] while parsing functions but got a [function_score] instead",
                "line": x (where "" is visible in Render snippet),
                "col": x (where "" is visible in Render snippet)
            }
        ],
"type": "x_content_parse_exception",
        "reason": " x (where "" is visible in Render snippet),[bool] failed to parse field [must]",
        "caused_by": {
            "type": "parsing_exception",
            "reason": "failed to parse [START_OBJECT]. malformed query, expected a [VALUE_STRING] while parsing functions but got a [function_score] instead",
            "line":  x (where "" is visible in Render snippet),,
            "col":  x (where "" is visible in Render snippet),
        }

Without mustache values it's working fine. Also I noticed in some cases if you surround empty double quotes with random functions it tends to work sometimes. Seems Elastic don't like must cases starting with empty double quotes.

try it.

 "must": {
                        "function_score": {
                            "functions": [
                                {{^isLocationFunctionNeeded}},
                                {
                                    "exp": {
                                        "location": {
                                            "origin": {
                                                "lat": "0.0",
                                                "lon": "0.0"
                                            },
                                            "offset": "1km",
                                            "scale": "50km"
                                        }
                                    }
                                },
                                {{/isLocationFunctionNeeded}},
                                {
                                    "random_score": {},
                                    "weight": 0.00001
                                }
                            ],
                            "score_mode": "sum"
                        }
                    }

I've tried that and I am getting error while uploading template to ELK:

Snippet:

"reason": "com.fasterxml.jackson.core.JsonParseException: Unexpected character ('{' (code 123)): was expecting double-quote to start field name\n at

try it.

POST /_scripts/function_template
{
	"script": {
		"lang": "mustache",
		"source": """{
			"must": {
				"function_score": {
					"functions": [
						{{^isLocationFunctionNeeded}}
						{
							"exp": {
								"location": {
									"lat": "0.0",
									"lon": "0.0"
								},
								"offset": "1km",
								"scale": "50km"
							}
						},
						{{/isLocationFunctionNeeded}}
						{
							"random_score": {},
							"weight": 0.00001
						}
					],
					"score_mode": "sum"
				}
			}
		}"""
	}
}

GET /_render/template
{
	"id": "function_template",
	"params": {}
}
1 Like

No use still cannot upload script to ELK engine. I took exact code you wrote to test it out.


{
    "error": {
        "root_cause": [
            {
                "type": "x_content_parse_exception",
                "reason": "[4:19] [stored script source] failed to parse object"
            }
        ],
        "type": "x_content_parse_exception",
        "reason": "[4:19] [stored script source] failed to parse object",
        "caused_by": {
            "type": "json_parse_exception",
            "reason": "Unexpected character ('{' (code 123)): was expecting comma to separate Object entries\n at [Source: (org.elasticsearch.common.io.stream.ByteBufferStreamInput); line: 4, column: 22]"
        }
    },
    "status": 400
}

Ok. Issue seems that in Postman it's not working, but in DEV tools it is working. Maybe you know how is that? :slight_smile:

1 Like

Maybe it works in elasticsearch. :smiley:

Seems that you cannot use the triple quotes (e.g. when using Postman), you need to send it as a one-line string and escape all quote characters:

POST _scripts/example_template
{
  "script": {
    "lang": "mustache",
    "source": " { \"query\": { \"bool\": { \"must\": { \"function_score\": { \"functions\": [ {{^isLocationFunctionNeeded}} { \"exp\": { \"location\": { \"lat\": \"0.0\",  \"lon\": \"0.0\" }, \"offset\": \"1km\", \"scale\": \"50km\" } }, {{/isLocationFunctionNeeded}} { \"random_score\": {}, \"weight\": 0.00001 } ], \"score_mode\": \"sum\" }}}}"
  }
}

Basically from DEV tools perspective you are correct with triple double quotes. It solves the problem. But if you want to use other tools it has to be escaped one-line. :smiley:

1 Like