The Addressfield module stores country and state information in the database as abbreviations such as NY for New York and US for United States. Unfortunately, this is how the Search API indexes the information meaning that the an aggregated fulltext search filter will not return results for 'United States' and 'New York' but only for US and NY. The Search API faceted search blocks for the Addressfield's country field does show the full name of the country but only the abbreviated letters for the state.

The Search API does have an API hook to alter the values of the items being indexed, function hook_search_api_index_items_alter(array &$items, SearchApiIndex $index), however, I can not find a way to change the values of the country and state abbreviations to the full name using any Addressfield module's functions.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

drunken monkey’s picture

Category: feature » support
Status: Active » Fixed

Indeed, you can alter the values with a hook, or by writing a data alteration (or preprocessor) to do it. With a processor, you could also alter the data at search time, if you want.

For having the correct names in the facets, the Adressfield module is responsible to specify its field information correctly. It seems to only do that for the country, not the state.

And with the Adressfield functions you need, I can of course not help you. If you really don't find anything, ask in the issue queue for that module.

Damien Tournoud’s picture

Project: Search API » Address Field
Version: 7.x-1.0-beta9 » 7.x-1.x-dev
Category: support » bug
Status: Fixed » Active

This one belongs to me.

rooby’s picture

Related to this (I can open a new issue if you prefer):

When I include the addressfield 'Administrative area (i.e. State / Province)' as a field in my index I get the following error when doing a search on that content:

Fatal error: [] operator not supported for strings in /var/www/mysite/profiles/myprofile/modules/contrib/search_api/search_api.module on line 1495

rooby’s picture

Actually, the problem mentioned in #3 occurs for all parts of the addressfield, not just Administrative area.

drewish’s picture

One other thing that'd be great is if we could get the name line indexed. Right now I'm combining them in a view field but the downside is it's un-sortable.

cthiebault’s picture

Any news on this issue?

Robin Millette’s picture

amarcus’s picture

As an simple alternative, try out the addressfield_tokens module. Enabled the "Search index" display mode for your content type, and use the "Address components" field formatter to include the address components you care about for keyword searches.

rooby’s picture

Thanks for the module, it looks useful.

I'm guessing it isn't a full replacement for search api integration in addressfield though in that doesn't cover having search facets for different parts of the address? Like a post code facet or state/province facet.

amarcus’s picture

That's true, addressfield_tokens does not provide any facet support for addresses. But the location_taxonomize module, referenced above (#7), looks pretty useful for that. I haven't tried it (we ended up writing our own module to do the same thing), but the idea is: turn addresses into a hierarchical taxonomy that can then be used as a search facet. This is much easier than creating a custom facet from scratch for address fields.

adam_b’s picture

I've used location_taxonomize with facets - there are some bits that don't seem to be working perfectly (though I don't have much experience with facets, so don't know where the fault lies) but it does give me a list of cities for 1200+ records so far.

rooby’s picture

To be honest I think this module should be providing its own usable search api integration.

A number of my sites tend to have a large amount of modules to begin with and I'm not into adding more (including more complexity and unwanted taxonomy in this case) just to work around bugs.

I will check out location taxonomise though at some stage. A lot of people have been asking for such a module for a very long time.

I really hope I can get some time to investigate a fix to this bug sometime.

javdich’s picture

Any progress on this yet, or is the location_taxonomize module the only workaround at this point? It would be nice to have the option on how to store the state / province names

  • Option (1) Abbreviation - NY
  • Option (2) Full Name - New York
mrweiner’s picture

@jman05: I haven't found another way around this as of yet, and as such, so far, location_taxonomize seems like the way to go as far indexing goes. The problem still stands though that because data from address_filed is stored with the abbreviation, location_taxonomize grabs the state information in an abbreviated from as well. Unless I'm missing something, I can't get taxonomize to list the state in its full form.

Any ideas? I'm sure there are people who have gotten this working by now. The thread is 10 months old.

mrweiner’s picture

So, this doesn't fix anything on Address Field's end, but I came up with a workaround. Set up a view for your index, and add an exposed filter of type "Search: Fulltext Search". Under searched fields, select Aggregate Address (which will need to be enabled within your index). Then, add the below code into a custom module. It uses hook_form_alter to convert any instance of a full state name into its abbreviation before the search is sent. So, if a user searches for "California", the query is instead treated as "CA", which is how the data is indexed. I know it's another module to install, but is a much more lightweight alternative to using location_taxonomy.

<?php
function search_helper_form_alter(&$form, $form_state, $form_id) {

switch($form_id) {
        case 'views_exposed_form':
        $form['#validate'][] = 'no_commas';
  break; 
 }   
}
  
function no_commas($form, &$form_state) {
  $form_state['values'] = str_ireplace(".", '', $form_state['values']);
  $form_state['values'] = str_ireplace(",", '', $form_state['values']);
  $form_state['values'] = str_ireplace("alabama", 'al', $form_state['values']);
  $form_state['values'] = str_ireplace("alaska", 'ak', $form_state['values']);
  $form_state['values'] = str_ireplace("arizona", 'az', $form_state['values']);
  $form_state['values'] = str_ireplace("arkansas", 'ar', $form_state['values']);
  $form_state['values'] = str_ireplace("california", 'ca', $form_state['values']);
  $form_state['values'] = str_ireplace("colorado", 'co', $form_state['values']);
  $form_state['values'] = str_ireplace("connecticut", 'ct', $form_state['values']);
  $form_state['values'] = str_ireplace("delaware", 'de', $form_state['values']);
  $form_state['values'] = str_ireplace("florida", 'fl', $form_state['values']);
  $form_state['values'] = str_ireplace("georgia", 'ga', $form_state['values']);
  $form_state['values'] = str_ireplace("hawaii", 'hi', $form_state['values']);
  $form_state['values'] = str_ireplace("idaho", 'id', $form_state['values']);
  $form_state['values'] = str_ireplace("illinois", 'il', $form_state['values']);
  $form_state['values'] = str_ireplace("indiana", 'in', $form_state['values']);
  $form_state['values'] = str_ireplace("iowa", 'ia', $form_state['values']);
  $form_state['values'] = str_ireplace("kansas", 'ka', $form_state['values']);
  $form_state['values'] = str_ireplace("kentucky", 'ky', $form_state['values']);
  $form_state['values'] = str_ireplace("louisiana", 'la', $form_state['values']);
  $form_state['values'] = str_ireplace("maine", 'me', $form_state['values']);
  $form_state['values'] = str_ireplace("maryland", 'md', $form_state['values']);
  $form_state['values'] = str_ireplace("michigan", 'mi', $form_state['values']);
  $form_state['values'] = str_ireplace("minnesota", 'mn', $form_state['values']);
  $form_state['values'] = str_ireplace("mississippi", 'ms', $form_state['values']);
  $form_state['values'] = str_ireplace("missouri", 'mo', $form_state['values']);
  $form_state['values'] = str_ireplace("montana", 'mt', $form_state['values']);
  $form_state['values'] = str_ireplace("nebraska", 'ne', $form_state['values']);
  $form_state['values'] = str_ireplace("nevada", 'nv', $form_state['values']);
  $form_state['values'] = str_ireplace("new hampshire", 'nh', $form_state['values']);
  $form_state['values'] = str_ireplace("new jersey", 'nj', $form_state['values']);
  $form_state['values'] = str_ireplace("new mexico", 'nm', $form_state['values']);
  $form_state['values'] = str_ireplace("new york", 'ny', $form_state['values']);
  $form_state['values'] = str_ireplace("new jersey", 'nj', $form_state['values']);
  $form_state['values'] = str_ireplace("north carolina", 'nc', $form_state['values']);
  $form_state['values'] = str_ireplace("north dakota", 'nd', $form_state['values']);
  $form_state['values'] = str_ireplace("ohio", 'oh', $form_state['values']);
  $form_state['values'] = str_ireplace("oklahoma", 'ok', $form_state['values']);
  $form_state['values'] = str_ireplace("oregon", 'or', $form_state['values']);
  $form_state['values'] = str_ireplace("pennsylvania", 'pa', $form_state['values']);
  $form_state['values'] = str_ireplace("rhode island", 'ri', $form_state['values']);
  $form_state['values'] = str_ireplace("south carolina", 'sc', $form_state['values']);
  $form_state['values'] = str_ireplace("south dakota", 'sd', $form_state['values']);
  $form_state['values'] = str_ireplace("tennessee", 'tn', $form_state['values']);
  $form_state['values'] = str_ireplace("texas", 'tx', $form_state['values']);
  $form_state['values'] = str_ireplace("utah", 'ut', $form_state['values']);
  $form_state['values'] = str_ireplace("vermont", 'vt', $form_state['values']);
  $form_state['values'] = str_ireplace("virginia", 'va', $form_state['values']);
  $form_state['values'] = str_ireplace("washington", 'wa', $form_state['values']);
  $form_state['values'] = str_ireplace("west virginia", 'wv', $form_state['values']);
  $form_state['values'] = str_ireplace("wisconsin", 'wi', $form_state['values']);
  $form_state['values'] = str_ireplace("wyoming", 'wy', $form_state['values']);
}
javdich’s picture

@ mrweiner Thanks for the post! that seems like a logical lightweight alternative. Although I'm using search pages, not views for my output, so I may have to re-evaluate views vs search pages...

mrweiner’s picture

I'm not familiar with using search pages instead of views, but if your search form has a form id, which I would assume it does, you can apply this to that as well.

javdich’s picture

Yes I believe in my case the form id for my search page = search_api_page_search_form

rszrama’s picture

Component: Miscellaneous » Code
Category: bug » feature

Just updating this to point to #1829900: [meta] Address Field 2.x needs pluggable administrative areas and an actual API; this is a solid feature request, but as of right now we have no API to get at those full text administrative area names or any way to indicate that a module like Search API could make use of full text names for a given country.

kevinquillen’s picture

Issue summary: View changes

To be honest I think this module should be providing its own usable search api integration.

To add to that, the values that get indexed are all lowercase. Why doesn't it get indexed the way it is in the database (PA, MD, etc)?

bojanz’s picture

We now have an API for getting administrative area names: addressfield_get_administrative_areas().
So someone can write a patch for this issue.

temkin’s picture

Project: Address Field » Search API
Component: Code » Framework
Status: Active » Needs review
FileSize
4.3 KB

Moving this issue back to Search API module as it belongs there, since addressfield already provides necessary API for that.

Based on what I see country value is already indexed as an abbreviation and a full text ("US United States"), but administrative_area (states) are still indexed as abbreviation only. I've created a new preprocessor that appends full text value of administrative_area to its abbreviation in order to index both values.

Patch attached.

drunken monkey’s picture

Project: Search API » Address Field
Component: Framework » Code
Status: Needs review » Needs work

Thanks a lot for providing a patch!

However, since the code is specific to the Addressfield module, I'd prefer it if this could be committed there. I generally don't included processors which are just specific to a single module in the Search API. I also think it's more customary to have a plugin for module A specific to module B in module B, not module A.

Regarding the processor class itself: I think this will give the processor a "Fields" select list in its config form which will then just be ignored, which would be confusing to users. Instead, you should change the code to have only the applicable fields in that select list, and then override processField() instead of preprocessIndexItems(), which will automatically only run on the fields selected by the user.

temkin’s picture

Thanks drunken monkey,

I'm fine with moving this patch to addressfield module, if maintainers agree to that. Strictly speaking, the logic about modules A and B could be applied in both directions here, as this patch is relevant to Search API just as much as to Addressfield.

Personally, I think it should be a part of Search API with other processors as you have an infrastructure there and IMO they all should sit in one place. But as I said, I'm fine with moving it to addressfield also. Is there any other module that implements preprocess on its side?

I tried to use processField() before switching to preprocessIndexItems(), but if I remember correctly there was no option for me to get country field value while preprocessing state field. It's needed for an API call. Technically, this patch only works for State field for now, as other fields are indexed fine. Therefore I'll probably hide field selection in admin UI all together as it doesn't make sense there.

Thanks again for your review!

temkin’s picture

Status: Needs work » Needs review
FileSize
4.04 KB

Here is a new patch against Addressfield module vs. Search API as the previous one. I also removed field config settings as the patch only processes state field, therefore it doesn't make sense to give user any options to choose.

RAFA3L’s picture

Thanks temkin,

Just what I was looking for today! the only thing is that I think the abbreviation in the facets is not necessary, but is easy to change. Thanks again.

rcodina’s picture

Patch on #25 doesn't work for me on addressfield 7.x-1.2+8-dev and search api 7.x-1.19.

rcodina’s picture

Sorry, patch on #25 does work but there is a case it doesn't: when the address field is not directly on the node and you have to first add the related node to index the address field. Anyone can confirm this problem?

I also think abbreviation is not necessary on facets!

Thanks for the patch!

rcodina’s picture

I've solved problems with addressfield in related entities with this patch. Please test it!

rcodina’s picture

Title: Integrate Search API with Addressfield » Integrate Addressfield with Search API
rcodina’s picture

FileSize
3.6 KB

I upload the interdiff with patch on #25.

rcodina’s picture

I update a new patch to fix administrative areas of countries which doesn't have them. In these cases I replace the empty value with the translatable string ''Whole country". I upload the interdiff with patch on #25. Please, review the patch!

rcodina’s picture

rcodina’s picture

FileSize
5.41 KB
3.34 KB

I upload a new patch where I add again the abbreviation given I found out it's necessary when you want to filter views with contextual filters. I upload the interdiff with patch on #25. I also have replaced ''Whole country" for "All" which is translated by default on Drupal core. Please, review the patch!

chriscalip’s picture

Patch #34
Shallow Review: +1
I enabled addressfield, search_api, search_api_algolia
I can see "field_cap_adress:administrative_area": "IL Illinois" on search index.
Works as advertised.

Anyone interested in similar patch drupal 8 address module needs help on RTBC.
https://www.drupal.org/node/2812659

kumkum29’s picture

Hello,

i have a similar problem on my site with search Api and adressField (from a related entity) (see https://www.drupal.org/node/2870433). The datas for the postal codes seems not to be saved when I reindexes the nodes.

Is this patch solves this problem?

Thanks.

mlncn’s picture

The original issue mentioned making this work for Facets. Has that goal been dropped from this issue?

With and without this patch, configuring a facet for "Administrative area" (state or province) to use "List item label" has no effect, and "Transform entity id into label" (which is the one i'd expect to work) causes a fatal error when viewing a page where facets should appear.

If that's not to be fixed in this issue, we should open another issue for it, as Facets thinks that should be fixed in Address: #2732379: ListItemProcessor doesn't work with some field properties

hargobind’s picture

From #22, @temkin writes:

Based on what I see country value is already indexed as an abbreviation and a full text ("US United States"), but administrative_area (states) are still indexed as abbreviation only. I've created a new preprocessor that appends full text value of administrative_area to its abbreviation in order to index both values.

I may be missing something obvious, but I'm not seeing where country names are expanded to their full text name.

So I wrote a SearchAPI processor to handle the conversion of 2-letter country codes into full text country names. Check out my sandbox Search API Addressfield Country Name. Feel free to add this processor to the ongoing patch here. FYI, I took the "field" approach with my processor, but that can be easily converted into the approach from the previous patches.

ugintl’s picture

Does your module provides the same functionality as the patch? Does it completely integrates searchapi with addressfield? I mean in addition to country, also indexes states and cities.

Have you used location taxonomize with addressfield?

ilericiler’s picture

Addressfield_autocomplete / location_taxonomize problem. Could not get help from related module issue pages.

When addressfield_autocomplete module is active, location_taxonomize/location_taxonomize_af module can not parse location as taxonomy terms.
The alternative "addressfield_geocomplete" works normally but, it doesnt support map pinning.

The server is ready to debug and all necessary files are editable. I will be sending the password (Same for Drupal User & Folder Access) if you can help me. Thank you.

http://www.ilankar.com/_help.htm

jeffwpetersen’s picture

Additionally the locality(city) facet is returning "New " and "York" and not "New York."

cmseasy’s picture

Patch works ok

@jeffwpetersen: maybe you used full text and not strings in the search api field setting?