# Accessing Child Index data using Java Custom Score Script

**URL:** <https://discuss.elastic.co/t/accessing-child-index-data-using-java-custom-score-script/10356>\
**Category:** Elasticsearch\
**Created:** [January 15, 2013, 5:09pm UTC](https://discuss.elastic.co/t/accessing-child-index-data-using-java-custom-score-script/10356 "2013-01-15T17:09:57Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Amy\_Lau](https://avatars.discourse-cdn.com/v4/letter/a/e47774/32.png) [@Amy\_Lau](https://discuss.elastic.co/u/Amy_Lau)\
**Post date:** [January 15, 2013, 5:09pm UTC](https://discuss.elastic.co/t/accessing-child-index-data-using-java-custom-score-script/10356/1 "2013-01-15T17:09:57Z")

</div>

I have been using custom score which required the data from a child  
index from the matched parent. I cannot find a way to access the child data  
from the Doc object or Source object in Java. The only way I can find to  
access the child data is to use a NodeClient or TransportClient object,  
which seems quite inefficent as the code is already running by  
elasticsearch itself and on it's classpath. Is there a better way to access  
the child data directly instead of using a transportClient like the code  
shown below? (The child data is to keep track of user selection of the  
parent data).

public double runAsDouble() {

```
String parentKey = doc().field("parentId").getStringValue();
String childKey = user + "_" + parentKey ;

//The TransportClient object with host and port# is created in the 

```

Constructor of the custom script

```
GetResponse resp = transportClient.prepareGet(INDEX, CHILD_TYPE, 

```

childKey).execute().actionGet();  
long field = resp.getVersion();

```
if (field <= 0)
 return Double.valueOf(1.0);
else
 return Double.valueOf(field+1);

```

}

--

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 15, 2013, 10:49pm UTC](https://discuss.elastic.co/t/accessing-child-index-data-using-java-custom-score-script/10356/2 "2013-01-15T22:49:57Z")

</div>

If you can wrap this data from a child into a number, you can do something  
like this:

"custom\_score": {  
"query": {  
"top\_children": {  
"query": {  
"custom\_score": {  
"query": { ... },  
"script": _script1_,  
}  
},  
"score": "max"  
}  
},  
"script": _script2_  
}

So, _script1_ will wrap whatever information you can get from child and  
pass it to _script2_ as \_score. That might not be what you asked for, but  
the next best thing I can think of is injecting NodeClient and using it to  
lookup the data that you need.

Igor

On Tuesday, January 15, 2013 12:09:57 PM UTC-5, Amy Lau wrote:

> I have been using custom score which required the data from a child  
> index from the matched parent. I cannot find a way to access the child data  
> from the Doc object or Source object in Java. The only way I can find to  
> access the child data is to use a NodeClient or TransportClient object,  
> which seems quite inefficent as the code is already running by  
> elasticsearch itself and on it's classpath. Is there a better way to access  
> the child data directly instead of using a transportClient like the code  
> shown below? (The child data is to keep track of user selection of the  
> parent data).
> 
> public double runAsDouble() {
> 
> ```
> String parentKey = doc().field("parentId").getStringValue();
> String childKey = user + "_" + parentKey ;
> 
> //The TransportClient object with host and port# is created in the 
> 
> ```
> 
> Constructor of the custom script
> 
> ```
> GetResponse resp = transportClient.prepareGet(INDEX, CHILD_TYPE, 
> 
> ```
> 
> childKey).execute().actionGet();  
> long field = resp.getVersion();
> 
> ```
> if (field <= 0)
> return Double.valueOf(1.0);
> else
> return Double.valueOf(field+1);
> 
> ```
> 
> }

--

---

<div class="post-metadata">

**Author:** ![Amy\_Lau](https://avatars.discourse-cdn.com/v4/letter/a/e47774/32.png) [@Amy\_Lau](https://discuss.elastic.co/u/Amy_Lau)\
**Post date:** [January 16, 2013, 4:02pm UTC](https://discuss.elastic.co/t/accessing-child-index-data-using-java-custom-score-script/10356/3 "2013-01-16T16:02:37Z")

</div>

Thanks for the reply. However, what you suggest doesn't seem that different  
than what I am doing to access child data, since script1 will still have to  
access the data through either a NodeClient or a TransportClient. I think  
if I can construct a TransportClient (or NodeClient) during elasticsearch  
startup and just use that instead of keep creating instances in the custom  
script constructor, that should be better...

Is there a way to create Custom startup script in java and run that somehow  
in elasticsearch startup?

On Tuesday, January 15, 2013 5:49:57 PM UTC-5, Igor Motov wrote:

> If you can wrap this data from a child into a number, you can do something  
> like this:
> 
> "custom\_score": {  
> "query": {  
> "top\_children": {  
> "query": {  
> "custom\_score": {  
> "query": { ... },  
> "script": _script1_,  
> }  
> },  
> "score": "max"  
> }  
> },  
> "script": _script2_  
> }
> 
> So, _script1_ will wrap whatever information you can get from child and  
> pass it to _script2_ as \_score. That might not be what you asked for, but  
> the next best thing I can think of is injecting NodeClient and using it to  
> lookup the data that you need.
> 
> Igor

--

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 16, 2013, 5:40pm UTC](https://discuss.elastic.co/t/accessing-child-index-data-using-java-custom-score-script/10356/4 "2013-01-16T17:40:19Z")

</div>

Maybe I misunderstood your question. I think there is a difference since  
script1 will be running on child documents, so it will be able to access  
child data using document or field lookup.

You don't need to construct NodeClient or TransportClient during startup,  
you can simply inject Node into you Script Factory and then pass it to the  
script during it's creation. I think something like this should work:

```
public static class Factory implements NativeScriptFactory {
    private Node node;

    @Inject
    public Factory(Node node) {
        this.node = node;
    }

    @Override
    public ExecutableScript newScript(@Nullable Map<String, Object> 

```

params) {  
Client client = node.client();  
// Parse other parameters  
return new MyScript(client, ... other parameters ... );  
}  
}

On Wednesday, January 16, 2013 11:02:37 AM UTC-5, Amy Lau wrote:

> Thanks for the reply. However, what you suggest doesn't seem that  
> different than what I am doing to access child data, since script1 will  
> still have to access the data through either a NodeClient or a  
> TransportClient. I think if I can construct a TransportClient (or  
> NodeClient) during elasticsearch startup and just use that instead of keep  
> creating instances in the custom script constructor, that should be  
> better...
> 
> Is there a way to create Custom startup script in java and run  
> that somehow in elasticsearch startup?
> 
> On Tuesday, January 15, 2013 5:49:57 PM UTC-5, Igor Motov wrote:
> 
> > If you can wrap this data from a child into a number, you can do  
> > something like this:
> > 
> > "custom\_score": {  
> > "query": {  
> > "top\_children": {  
> > "query": {  
> > "custom\_score": {  
> > "query": { ... },  
> > "script": _script1_,  
> > }  
> > },  
> > "score": "max"  
> > }  
> > },  
> > "script": _script2_  
> > }
> > 
> > So, _script1_ will wrap whatever information you can get from child and  
> > pass it to _script2_ as \_score. That might not be what you asked for,  
> > but the next best thing I can think of is injecting NodeClient and using it  
> > to lookup the data that you need.
> > 
> > Igor

--

---

<div class="post-metadata">

**Author:** ![Amy\_Lau](https://avatars.discourse-cdn.com/v4/letter/a/e47774/32.png) [@Amy\_Lau](https://discuss.elastic.co/u/Amy_Lau)\
**Post date:** [January 16, 2013, 9:59pm UTC](https://discuss.elastic.co/t/accessing-child-index-data-using-java-custom-score-script/10356/5 "2013-01-16T21:59:35Z")

</div>

Thanks so much for the answer, Igor. I think the injected Node client  
should work for me. I am going to try and see.

--

---

<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:** [July 6, 2017, 2:56am UTC](https://discuss.elastic.co/t/accessing-child-index-data-using-java-custom-score-script/10356/6 "2017-07-06T02:56:02Z")

</div>


