Gravatar for wvuong@captechconsulting.com

Question by wvuong, Dec 18, 2015 9:14 AM

Geolocalized results with multiple locations per item

I would like to get results that are geolocalized. I have found this documentation, but my unique case is that each item has a list locations and I want to return the item ands its location(s) that are within the specified radius.

I am wondering about the best practice for going about this. I think I could make my own function that traverses each item's list of lat/longs and compares that with the reference point, while adding the in range locations to a temporary field and also setting a temporary field for the distance value for the closet location so that I can sort my results.

Any thoughts on this would be gerat

1 Reply
Gravatar for jflheureux@coveo.com

Answer by Jean-François L'Heureux, Dec 18, 2015 9:59 AM

Is this question related to your question about returning array from a computed index field? https://answers.coveo.com/questions/5342/returning-array-from-a-computed-field

To work, the dist query function needs the lat and long to be in floating point fields inside the CES index. As I explained in the other question, the only way to store multiple values in a single CES field is with the string field type and the multi-value facet option.

I see 2 options for your use case:

  1. Index the various locations in separate fields. If you know an item won't have more than 5 locations, you can create 5 pair of computed index fields for your locations lat and long fields.
  2. Index each Sitecore item multiple times with a different location in each. You can do this by creating a processor for the <coveoPostItemProcessingPipeline>. There's documentation and examples in those 2 links: link1, link2. In the processor, you wold duplicate the item as many time as the number of locations and keep only one location per item. The unique ID of each item must be different, thus I suggest to include the location information in the unique ID strings. You can then merge the search results together in the UI with various methods.
Gravatar for wvuong@captechconsulting.com

Comment by wvuong, Dec 18, 2015 10:40 AM

This was somewhat related to the question about returning the array. I wanted to return an array in order to more easily parse my output. The default handling of indexing the value with colon separations provided me what I needed.

I will implement option 2 as I want it to support a dynamic number of locations.

Thanks

Gravatar for wvuong@captechconsulting.com

Comment by wvuong, Dec 18, 2015 11:25 AM

I have followed the "TranslatedItem" post processor tutorial but don't seem to be getting the expected results. My OutputCoveoItems contains a list of all the new items that correspond to a location, but upon inspecting my index through the CES Admin panel, there is only one item and it has the values that I modified

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Dec 18, 2015 4:53 PM

Is it possible that the UniqueID property of all your items is the same? It needs to be different for all the items you want to index.

Gravatar for wvuong@captechconsulting.com

Comment by wvuong, Dec 21, 2015 9:55 AM

I thought I could append whatever values onto the unique id, but im pretty certain i have to follow this "sitecore://{database}/{item_id}?lang={language}&ver={version}." pattern.

What methods would you suggest to merge the results together? I thought about merging them after I have receive each page of results, but then this could mean I don't get "10" results, because of merging ones together.

I tried to find a pipeline that is called to check if a item should be added to the results list but didn't see one.

Would there be a way to check against some field I specify where if an item in the results list already exists with the value of this field, don't add it.

Gravatar for wvuong@captechconsulting.com

Comment by wvuong, Dec 21, 2015 11:10 AM

I would basically like to make my $qf to inject a field from dynamically calculated values like the dist function does

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Jan 4, 2016 4:23 PM

The merge operation on search results would be done by the index itself and the UI components. Have a look at those documentation pages:

  • https://developers.coveo.com/display/JsSearch/Folding+Component
  • https://developers.coveo.com/display/JsSearch/ResultFolding+Component
  • https://developers.coveo.com/display/JsSearch/FoldingForThread+Component
Gravatar for wvuong@captechconsulting.com

Comment by wvuong, Jan 4, 2016 4:32 PM

Alright, thanks! I'll try that.

How does this affect faceting? For instance I would like the facet's to show numerical values of possible results not including duplicates. Does this take that into consideration?

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Jan 4, 2016 4:39 PM

Facets will always show the number of values for the actual query. If the query returns duplicates, the facets count will include those duplicates as well.

A way to modify the query that is run for the facets is the data-additional-filter attribute on facets: https://developers.coveo.com/display/JsSearch/Facet+Component#FacetComponent-additionalFilter

You could add a filter to eliminate duplicates in that attribute.

Gravatar for wvuong@captechconsulting.com

Comment by wvuong, Jan 4, 2016 4:43 PM

I've looked at that and am not sure how to use Folding given what I am trying to accomplish.

Given an item with multiple locations; I would like to calculate the distances, find the closest one in order to display, facet against, sort, etc, on that one item.

Folding in my case seems like it wouldn't facet correctly or allow me to sort on the "child" that is closest.

One of the approaches I have tried involved creating a query extension and using Coveo.match to manually look through my items, calculate the distances, find the closest one, get its unique identifier, and add that to my result set. This allows me to display only the closest one while keeping faceting and sorting but theres a ten fold slow down which seems to come from the multiple calls to Coveo.match.

Ask a question