Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nested/object field access in scripts should throw an appropriate error #23719

Open
rjernst opened this issue Mar 23, 2017 · 9 comments
Open
Assignees
Labels
:Core/Infra/Scripting Scripting abstractions, Painless, and Mustache >enhancement help wanted adoptme Team:Core/Infra Meta label for core/infra team triaged Issue has been looked at, and is being left open

Comments

@rjernst
Copy link
Member

rjernst commented Mar 23, 2017

When trying to access a nested or object field within a script, the behavior is different depending on the method called. When trying to retrieve the value of the field, an exception is thrown saying the field does not exist (when it fact it is simply not a field mapper). If you try to check if the doc contains the field, it simply returns false, again incorrectly since the field does exist, just not as a field mapper. I think we should throw an error in both these cases, but with a good message that indicates the field exists but is not accessible in scripts. Note that I'm not sure what happens when trying to access a concrete field that is parented by a nested field. I believe I have seen issues for it before where the field just comes back as no values. I think we should throw an error in this case as well.

@rjernst rjernst added :Core/Infra/Scripting Scripting abstractions, Painless, and Mustache discuss >enhancement labels Mar 23, 2017
@clintongormley
Copy link
Contributor

+1 makes sense to give a useful exception when trying to access nested/object fields.

If you try to access a concrete field under nested today, it might succeed if include_in_parent/root are enabled. I think once include_in_parent/root are removed (see #12461) then we could throw an exception for concrete nested fields too.

@clintongormley clintongormley added help wanted adoptme and removed discuss labels Mar 24, 2017
@glefloch
Copy link
Contributor

Hi, can I take this issue?

@MrOrz
Copy link

MrOrz commented Feb 2, 2018

I wonder if this statement is still valid for Elasticsearch 6.1.0:

When trying to access a nested or object field within a script, the behavior is different depending on the method called. When trying to retrieve the value of the field, an exception is thrown saying the field does not exist (when it fact it is simply not a field mapper). If you try to check if the doc contains the field, it simply returns false, again incorrectly since the field does exist, just not as a field mapper.

In Elasticsearch 6.1.0, actually we can read and write nested objects in scripts, with no include_in_root nor include_in_parent in place.

Proof of concept

  1. Start a elasticsearch server on port 9200
  2. Follow the nested object guide to setup indexes and index an document:
curl -XPUT 'localhost:9200/my_index?pretty' -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "my_type": {
      "properties": {
        "user": {
          "type": "nested" 
        }
      }
    }
  }
}
'
curl -XPUT 'localhost:9200/my_index/my_type/1?pretty' -H 'Content-Type: application/json' -d'
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
'
  1. Mutate the indexed document's nested field with scripted update:
curl -POST 'localhost:9200/my_index/my_type/1/_update?pretty' -H 'Content-Type: application/json' -d'
{
  "script": {
    "source": "ctx._source.user.get(1).put(\"last\", \"SmithEX\");",
    "lang": "painless"
  }
}
'
  1. See the result:
curl -XGET 'localhost:9200/my_index/my_type/1?pretty'

It returns:

{
  "_index" : "my_index",
  "_type" : "my_type",
  "_id" : "1",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "group" : "fans",
    "user" : [
      {
        "first" : "John",
        "last" : "Smith"
      },
      {
        "first" : "Alice",
        "last" : "SmithEX"
      }
    ]
  }
}

Notice that the second user's last name is correctly mutated.

@rjernst
Copy link
Member Author

rjernst commented Feb 2, 2018

@MrOrz nested documents are always available via _source. This issue is about accessing them from docvalues within a scoring script for search.

@MrOrz
Copy link

MrOrz commented Feb 3, 2018

I see. Didn't notice the difference in subjects.
Thanks for the explanation!

@stu-elastic
Copy link
Contributor

In LeafDocLookup we should not return an assessor for nested or Object fields. Then when executing the script we can raise the appropriate error. It's possible to do this all within the get method of LeafDocLookup.

@rjernst rjernst added the Team:Core/Infra Meta label for core/infra team label May 4, 2020
@rjernst rjernst added the needs:triage Requires assignment of a team area label label Dec 3, 2020
@stu-elastic stu-elastic removed the needs:triage Requires assignment of a team area label label Dec 9, 2020
@Shitai-Roblox
Copy link

Hi Folks,

I am thinking if we support this now? I came from this https://discuss.elastic.co/t/can-not-access-array-with-objects-in-painless/198226.

@thecoop
Copy link
Member

thecoop commented Nov 1, 2024

@rjernst Is this still something we're going to fix at some point?

@thecoop thecoop added the triaged Issue has been looked at, and is being left open label Nov 1, 2024
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (Team:Core/Infra)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Core/Infra/Scripting Scripting abstractions, Painless, and Mustache >enhancement help wanted adoptme Team:Core/Infra Meta label for core/infra team triaged Issue has been looked at, and is being left open
Projects
None yet
Development

No branches or pull requests