# Multi\_field with collection value using Java api

**URL:** <https://discuss.elastic.co/t/multi-field-with-collection-value-using-java-api/9309>\
**Category:** Elasticsearch\
**Created:** [October 10, 2012, 6:35pm UTC](https://discuss.elastic.co/t/multi-field-with-collection-value-using-java-api/9309 "2012-10-10T18:35:58Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![fletch](https://avatars.discourse-cdn.com/v4/letter/f/919ad9/32.png) [@fletch](https://discuss.elastic.co/u/fletch)\
**Post date:** [October 10, 2012, 6:35pm UTC](https://discuss.elastic.co/t/multi-field-with-collection-value-using-java-api/9309/1 "2012-10-10T18:35:58Z")

</div>

Hi all,

I'm coming across some odd behavior and wondering if I'm missing something  
or if it's a bug.

I created an index (see script below), and added some documents. There is  
a mapping for a multi\_field type, and objects of type java.util.List are  
used as values. When I pull back a single document using curl, the json  
looks like I would expect. However, when I do a simple bool query using  
the Java api against the same index, the multi\_field property is nested  
inside an extra ArrayList. This ArrayList has a single entry, which is the  
list I expect. Where did the extra wrapping collection come from? I know  
it has to do with using the multi\_field type, because when I map the  
property directly to a string type it works as I would expect. And the  
returned json doesn't change when I use curl...

Please let me know if any of the above needs clarification... not as easy  
to copy and paste in java objects as it is json. 🙂

Thanks in advance for any insights.  
Matt

Index creation script:  
curl -XPUT [http://server:9200/photoindex1/](http://server:9200/photoindex1/) -d @photoIndex1.json

photoIndex1.json (abbreviated):  
{  
"settings" : {  
"analysis" : {  
"analyzer" : {  
"stemmingloweringanalyzer" : {  
"type" : "custom",  
"tokenizer" : "lowercase",  
"filter" : ["porterStem"]  
}  
}  
}  
},  
"mappings" : {  
"photoType" : {  
"\_source" : {  
"enabled" : true  
},  
"\_all" : {  
"analyzer" : "default",  
"enabled" : true  
},  
"properties" : {  
"photoId" : {  
"type" : "integer",  
"store" : "yes",  
"index" : "no",  
"include\_in\_all" : false  
},  
"tags" : {  
"type" : "multi\_field",  
"fields" : {  
"tags" : {  
"type" : "string",  
"index\_name" : "tag",  
"store" : "no",  
"index" : "analyzed",  
"analyzer" : "stemmingloweringanalyzer",  
"include\_in\_all" : true,  
"boost" : 0.7  
},  
"untouched" : {  
"type" : "string",  
"index\_name" : "tag",  
"store" : "yes",  
"index" : "not\_analyzed"  
}  
}  
}  
}  
}  
}  
}

Get a document using curl (doesn't change if I reindex without the  
multi\_field type and instead have a mapping to string type):  
curl -XGET [http://dsearchin001:9200/photoalias/photoType/40](http://dsearchin001:9200/photoalias/photoType/40)  
{  
"\_index":"photoindex1",  
"\_type":"photoType",  
"\_id":"40",  
"\_version":1,  
"exists":true,  
"\_source" : {  
"tags": ["white kitchen cabinets","light brown granite counter  
tops","recessed can lights","stainless steel refrigerator","bright"],  
"photoId":40  
}  
}

Java code that I would expect to work....  
protected List extractListField(String fieldName, SearchHit hit,  
Class genericClass)  
{  
Map\<String, SearchHitField\> fieldMap = hit.getFields();  
SearchHitField hitField = fieldMap.get(fieldName);  
List list = Lists.newLinkedList();  
if (hitField != null && hitField.getValues() != null &&  
!hitField.getValues().isEmpty())  
{  
Collection values = (Collection) hitField.getValues();  
list.addAll(values);  
}  
return list;  
}

Java code I actually have to use...  
protected List extractListField(String fieldName, SearchHit hit,  
Class genericClass)  
{  
Map\<String, SearchHitField\> fieldMap = hit.getFields();  
SearchHitField hitField = fieldMap.get(fieldName);  
List list = Lists.newLinkedList();  
if (hitField != null && hitField.getValues() != null &&  
!hitField.getValues().isEmpty())  
{  
// Note the use of getValue() instead of getValues()  
Collection values = (Collection) hitField.getValue();  
list.addAll(values);  
}  
return list;  
}

--

---

<div class="post-metadata">

**Author:** ![Clinton\_Gormley](https://avatars.discourse-cdn.com/v4/letter/c/50afbb/32.png) [@Clinton\_Gormley](https://discuss.elastic.co/u/Clinton_Gormley)\
**Post date:** [October 11, 2012, 8:03am UTC](https://discuss.elastic.co/t/multi-field-with-collection-value-using-java-api/9309/2 "2012-10-11T08:03:11Z")

</div>

Hi Fletch

> I created an index (see script below), and added some documents.  
> There is a mapping for a multi\_field type, and objects of type  
> java.util.List are used as values. When I pull back a single document  
> using curl, the json looks like I would expect. However, when I do a  
> simple bool query using the Java api against the same index, the  
> multi\_field property is nested inside an extra ArrayList. This  
> ArrayList has a single entry, which is the list I expect. Where did  
> the extra wrapping collection come from? I know it has to do with  
> using the multi\_field type, because when I map the property directly  
> to a string type it works as I would expect. And the returned json  
> doesn't change when I use curl...

The JSON that you send to ES is stored in the \_source field, and that  
exact same JSON is returned to you when you request a document (via GET  
or search or whatever).

This is distinct from the values that are indexed for that document.

A multi-field (eg you have field 'title' and add multi-fields  
'untouched' and 'autocomplete') results in the value from the 'title'  
field being indexed into all sub-fields:

- title.title (the main field, also accessible as 'title')
- title.untouched
- title.autocomplete

This is the reason you're seeing a difference, and it is not a bug. It  
is like this by design

clint

--

---

<div class="post-metadata">

**Author:** ![fletch](https://avatars.discourse-cdn.com/v4/letter/f/919ad9/32.png) [@fletch](https://discuss.elastic.co/u/fletch)\
**Post date:** [October 11, 2012, 6:10pm UTC](https://discuss.elastic.co/t/multi-field-with-collection-value-using-java-api/9309/3 "2012-10-11T18:10:53Z")

</div>

Hi Clint,

Thanks for the reply. I believe I understand the difference between what  
is stored in \_source and what is indexed. What I'm really trying to get at  
is that when I write build up a query in Java, the SearchHitField comes  
back with a different value depending on whether I map the field as  
multifield or not, while the json response (running exactly the same query  
-- got from toString() value on ES SearchRequestBuilder instance) does not  
change at all. Just seems odd to me that one data representation changes  
and the other doesn't...

Sorry if I didn't explain this well the first time.  
Matt

PS - Here's the json representation of the query I'm running, in case that  
makes a difference:  
{  
"size" : 1,  
"query" : {  
"bool" : {  
"should" : [ {  
"field" : {  
"primarySpaceDesc" : {  
"query" : "Attic",  
"boost" : 5.0  
}  
}  
}, {  
"field" : {  
"secondarySpaceDesc" : "Attic"  
}  
} ]  
}  
},  
"fields" : [ "description", "displayTypeId", "photoId", "segmentDesc",  
"segmentId", "graphicId", "largeImageFilename", "mediumImageFilename",  
"primarySpaceDesc", "primarySpaceId", "primaryStyleDesc", "primaryStyleId",  
"secondarySpaceDesc", "secondarySpaceId", "secondaryStyleDesc",  
"secondaryStyleId", "smallImageFilename", "tags" ]  
}

On Thursday, October 11, 2012 2:03:17 AM UTC-6, Clinton Gormley wrote:

> Hi Fletch
> 
> > I created an index (see script below), and added some documents.  
> > There is a mapping for a multi\_field type, and objects of type  
> > java.util.List are used as values. When I pull back a single document  
> > using curl, the json looks like I would expect. However, when I do a  
> > simple bool query using the Java api against the same index, the  
> > multi\_field property is nested inside an extra ArrayList. This  
> > ArrayList has a single entry, which is the list I expect. Where did  
> > the extra wrapping collection come from? I know it has to do with  
> > using the multi\_field type, because when I map the property directly  
> > to a string type it works as I would expect. And the returned json  
> > doesn't change when I use curl...
> 
> The JSON that you send to ES is stored in the \_source field, and that  
> exact same JSON is returned to you when you request a document (via GET  
> or search or whatever).
> 
> This is distinct from the values that are indexed for that document.
> 
> A multi-field (eg you have field 'title' and add multi-fields  
> 'untouched' and 'autocomplete') results in the value from the 'title'  
> field being indexed into all sub-fields:
> 
> - title.title (the main field, also accessible as 'title')
> - title.untouched
> - title.autocomplete
> 
> This is the reason you're seeing a difference, and it is not a bug. It  
> is like this by design
> 
> clint

--

---

<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, 3:09am UTC](https://discuss.elastic.co/t/multi-field-with-collection-value-using-java-api/9309/4 "2017-07-06T03:09:14Z")

</div>


