Title: Store complex (i.e. label + id) meta data in SOLR document
Tags: solr;lucene
Question: I use SOLR to store documents having some meta data that is composed out of multiple values. Usually an id with a label. A simple example would be the name of a city and the unique id of that city. The id is needed, because different cities can have the same name like Berlin in Germany and Berlin in the US. The name is obvioulsy needed, because I want to search for that string.
If I use facets, I would like to get back two facets having the label "Berlin". If I restrict my search (using some other meta data field) to documents from germany, I would expect to get only one facet for the german Berlin. Obviously this does not work, if I store id and label in two seperated SOLR fields.
I would assume that this is not an uncommon requirement, but I was not able to find any useful information. My current approaches are:
Implement a complete custom field type in Java: Hard to estimate for me, because I'm currently just a SOLR user, not a SOLR developer.
Put id and label in a single string (like "123:Berlin" and "456:Berlin") and define custom field types in schema.xml using a custom analyzer which splits the value. Sound reasonable to me, but I'm not 100% sure if it will work with faceting.
I found some references to subfields, but only on older pages and I was not able to find useful documentation.
Is there some well known way to solve this in SOLR?

Here is the accepted answer: There seems no out of the box solution.
Your #2 should work fine with some client side modifications.
You can index your data with id_name as a single string field. Needs to
change at indexing time. Easier using Transformers if you are using
DIH.
You would have unique facets for each id now, and at Client
side you can always split the Facets for display.
You can also check Facet Pivots, which can provide an Hierarchical Faceting
Comment for this answer: In my case, by using #2, I have to set both 'id' and 'id+label' to be the same type, i.e., "string", and 'store' only. Otherwise, the facet(id) and facet(id+label) don't match.
Comment for this answer: Thanks for the optimistic feedback. But I don't get what you want to say in 2. Could you give more details? I don't understand what role DIH should play?!
Comment for this answer: #2 is the second option you had mentioned (without the numbering). Also DIH was just mentioned in case you are using it for Indexing in which case joining the fields would have been much easier. If you are using other techniques, it just needs to be handle at that side

Here is another answer: A rather simple suggestion: use two fields at the index time through copyField for values like "123:Berlin"
one notindexed and stored string field for faceting plus parsing/cleaning on the client side
and for search use the copy one indexed and not stored with a simple regex analyzer in ex: PatternReplaceCharFilterFactory.
No need for custom analyzers or new type of fields, just like you already pointed out in your second solution

Here is another answer: That should work. If you add a filter query such as fq=country_name:Germany, it should return facets for cities only in Germany. Please take a look at this example below:
Suppose you have 4 fields in your schema:
id, city_name, country_name, state_name
SAMPLE DATA:
city_name: Berlin
country_name: Germany
state_name: Some_State1
city_name: Berlin
country_name: USA
state_name: Some_State2
city_name: Dublin
country_name: Ireland
state_name: Some_State3
city_name: Dublin
country_name: USA
state_name: California
city_name: Dublin
country_name: USA
state_name: Virginia
If you want to get facet for all cities with name Dublin:
/select/?q=*:*&amp;facet=true&amp;facet.field=country_name&amp;facet.field=city_name&amp;fq=city_name:Dublin
In the result, the count of facet Dublin will be 3
Now if you want to get facet for all cities with name Dublin and restrict country to USA, your query will be:
/select/?q=*:*&amp;facet=true&amp;facet.field=country_name&amp;facet.field=city_name&amp;fq=city_name:Dublin&amp;fq=country_name:USA
In the result, the count for facet Dublin will be 2, because we have two Dublins in USA, one is in California and other in Virginia
NOTE: I added &amp;fq=country_name:USA
Comment for this answer: Have a look at my requirements. I explained why this is not enough. I need the ids of the facet values. And in your first query I would expect to get back to facets for Dublin.

Here is another answer: Pivot faceting can work.
Say you have the fields: cityId, cityName, country
Do a pivot facet over city-id, city-name by using query parameters:
facet.pivot=cityId,cityName
At the first level, like a standard facet, you will get each city ID.  But on the second level, you will get the name of each city.  Given that each city ID will have only one name, you can simply read each city ID's name from the next facet level (under the pivot element in the XML).
<lst name="facet_pivot"&gt;
<arr name="cityId,city"&gt;
<lst&gt;
<str name="field"&gt;cityId</str&gt;
<str name="value"&gt;1</str&gt;
<int name="count"&gt;1</int&gt;
<arr name="pivot"&gt;
<lst&gt;
<str name="field"&gt;city</str&gt;
<str name="value"&gt;berlin</str&gt;
<int name="count"&gt;1</int&gt;
</lst&gt;
</arr&gt;
</lst&gt;
<lst&gt;
<str name="field"&gt;cityId</str&gt;
<str name="value"&gt;2</str&gt;
<int name="count"&gt;1</int&gt;
<arr name="pivot"&gt;
<lst&gt;
<str name="field"&gt;city</str&gt;
<str name="value"&gt;berlin</str&gt;
<int name="count"&gt;1</int&gt;
</lst&gt;
</arr&gt;
</lst&gt;
<lst&gt;
<str name="field"&gt;cityId</str&gt;
<str name="value"&gt;3</str&gt;
<int name="count"&gt;1</int&gt;
<arr name="pivot"&gt;
<lst&gt;
<str name="field"&gt;city</str&gt;
<str name="value"&gt;melbourne</str&gt;
<int name="count"&gt;1</int&gt;
</lst&gt;
</arr&gt;
</lst&gt;
</arr&gt;
</lst&gt;
Basically, if the ID is unique, you will be guaranteed to only have one pivot value at the second level.
Optionally, if you want to group your 'Berlins' together, just reverse the order of the facet pivot and make it:
facet.pivot=cityName,cityId
and you will get 'Berlin' at the first level and possibly multiple IDs at the second level (and as a bonus, you could add a third level country so that you can read the country for each city off the third level).
Comment for this answer: Sounds like a good solution, if I had only one dimension to get facets for. But I have (as it's common for facets) multiple dimensions, so I would store (City + CityId), (Author + AuthorId), ... I think your solution will not work for multiple dimensions. Or am I missing something?
Comment for this answer: you should be able to facet pivots over multiple fields like hierarchy as i had pointed in my answers.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 4, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2013:00:05/20/13', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<solr><lucene>', 'Title': 'Store complex (i.e. label + id) meta data in SOLR document', 'ViewCount': 1328, 'id': 16657979, 'user_AboutMe': '<p>Beside programming I like Yoga, TaiChi and similar things</p>\n', 'user_AccountId': 38617.0, 'user_DisplayName': 'Achim', 'user_Reputation': 15119.0, 'user_Views': 1255.0, 'user_id': 110963.0}}