# Why contexts?

**URL:** <https://discuss.elastic.co/t/why-contexts/302957>\
**Category:** Elasticsearch\
**Tags:** painless\
**Created:** [April 21, 2022, 7:33pm UTC](https://discuss.elastic.co/t/why-contexts/302957 "2022-04-21T19:33:05Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![aleding](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/aleding/32/103504_2.png) [@aleding](https://discuss.elastic.co/u/aleding)\
**Post date:** [April 21, 2022, 7:33pm UTC](https://discuss.elastic.co/t/why-contexts/302957/1 "2022-04-21T19:33:05Z")

</div>

In debugging a Filebeat module, I have had to dig into Painless scripts & contexts which has led to several questions:

- Why contexts?

- Can the same data not be accessed via `_doc`? _(I've also seen this asked in other threads as well)_

- In the snippet below from the module I am debugging, the goal seems straightforward enough: set `_temp_.time` to the value of `{{sophos.xg.date}} {{sophos.xg.time}}`; but the `if` statement is where I am lost. There are similar statements all over the module but I am unable to find any reference that discusses the **use question marks in context references**. I'm sure there is a good reason - just can't find it...

```auto
- set:
    field: _temp_.time
    value: "{{sophos.xg.date}} {{sophos.xg.time}}"
    if: "ctx?.sophos?.xg?.date != null && ctx?.sophos?.xg?.time != null"

```

---

<div class="post-metadata">

**Author:** ![stephenb](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/stephenb/32/40856_2.png) [@stephenb](https://discuss.elastic.co/u/stephenb)\
**Post date:** [April 21, 2022, 7:45pm UTC](https://discuss.elastic.co/t/why-contexts/302957/2 "2022-04-21T19:45:38Z")

</div>

> [@aleding](#):
>
> I am unable to find any reference that discusses the **use question marks in context references**. I'm sure there is a good reason - just can't find it...

The ? marks are for null safety

From [this page section](https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest.html#conditionally-run-processor) down a bit

> Incoming documents often contain object fields. If a processor script attempts to access a field whose parent object does not exist, Elasticsearch returns a `NullPointerException` . To avoid these exceptions, use [null safe operators](https://www.elastic.co/guide/en/elasticsearch/painless/8.1/painless-operators-reference.html#null-safe-operator), such as `?.` , and write your scripts to be null safe.
> 
> For example, `ctx.network?.name.equalsIgnoreCase('Guest')` is not null safe. `ctx.network?.name` can return null. Rewrite the script as `'Guest'.equalsIgnoreCase(ctx.network?.name)` , which is null safe because `Guest` is always non-null.
> 
> If you can’t rewrite a script to be null safe, include an explicit null check.

---

<div class="post-metadata">

**Author:** ![aleding](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/aleding/32/103504_2.png) [@aleding](https://discuss.elastic.co/u/aleding)\
**Post date:** [April 21, 2022, 7:59pm UTC](https://discuss.elastic.co/t/why-contexts/302957/3 "2022-04-21T19:59:48Z")

</div>

Hi @stephenb - thanks for providing this. Now that I see it, I do believe I saw it last week when I was chatting with you about this module but that was before I started digging into Painless so it didn't register.

So using the snippet I provided:

- Is it basically protecting against any of `ctx`, `ctx.sophos`, or `ctx.sophos.xg` returning NULL?

- Also, if one knows for certain that `ctx.sophos` defintely exists, could this statement be used instead? `ctx.sophos.xg?`

---

<div class="post-metadata">

**Author:** ![stephenb](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/stephenb/32/40856_2.png) [@stephenb](https://discuss.elastic.co/u/stephenb)\
**Post date:** [April 21, 2022, 8:09pm UTC](https://discuss.elastic.co/t/why-contexts/302957/4 "2022-04-21T20:09:30Z")

</div>

> [@aleding](#):
>
> `"ctx?.sophos?.xg?.date`

Right to left protects agains `sophos` null, the `xg` null then `date` null

> [@aleding](#):
>
> Also, if one knows for certain that `ctx.sophos` defintely exists, could this statement be used instead? `ctx.sophos.xg?`

Yes probably but the ? are safer and recommended... it will crash the pipeline if you try to access a null.

I would follow the patterns shown as best practice

---

<div class="post-metadata">

**Author:** ![aleding](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/aleding/32/103504_2.png) [@aleding](https://discuss.elastic.co/u/aleding)\
**Post date:** [April 21, 2022, 8:16pm UTC](https://discuss.elastic.co/t/why-contexts/302957/5 "2022-04-21T20:16:21Z")

</div>

Understood - thank you.

Also, in trying to answer my own post asking "Why contexts?", it appears that Painless contexts are borrowed from Java but I'm not sure if I have this correct; can you confirm or deny?

---

<div class="post-metadata">

**Author:** ![stephenb](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/stephenb/32/40856_2.png) [@stephenb](https://discuss.elastic.co/u/stephenb)\
**Post date:** [April 21, 2022, 8:20pm UTC](https://discuss.elastic.co/t/why-contexts/302957/6 "2022-04-21T20:20:08Z")

</div>

I am not a painless expert... but it is related to Java... tons of docs if you really want to get into it.

---

<div class="post-metadata">

**Author:** ![aleding](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/aleding/32/103504_2.png) [@aleding](https://discuss.elastic.co/u/aleding)\
**Post date:** [April 21, 2022, 8:22pm UTC](https://discuss.elastic.co/t/why-contexts/302957/7 "2022-04-21T20:22:35Z")

</div>

> [@stephenb](#):
>
> tons of docs if you really want to get into it.

Believe me, I have been. The docs definitely reference Java quite a bit but as to why contexts exist in Painless; I've haven't seen that discussed but given the relation between the two, it just makes sense that it would be borrowed.

Thanks again...

---

<div class="post-metadata">

**Author:** ![stephenb](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/stephenb/32/40856_2.png) [@stephenb](https://discuss.elastic.co/u/stephenb)\
**Post date:** [April 21, 2022, 8:32pm UTC](https://discuss.elastic.co/t/why-contexts/302957/8 "2022-04-21T20:32:42Z")

</div>

> **[Painless contexts | Painless Scripting Language \[8.11\] | Elastic](https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-contexts.html)**

> A Painless script is evaluated within a context. Each context has values that are available as local variables, an allowlist that controls the available classes, and the methods and fields within those classes (API), and if and what type of value is returned.
> 
> Painless scripts typically run within one of the contexts in the following table. Before using a Painless context, [configure the example data](https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-context-examples.html). Each context example is configured to operate on this data.

Thats about as much as I know on the subject 😉

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [May 19, 2022, 8:33pm UTC](https://discuss.elastic.co/t/why-contexts/302957/9 "2022-05-19T20:33:12Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
