7
votes

Données de printemps Recherche élastique - Trier les emplacements Geo par distance

Étant donné un point de localisation Geo, j'essaie de trouver des sites à moins de 10 km et de le trier par le plus proche de l'emplacement donné.

J'ai réussi à retourner la liste des emplacements à moins de 10 km, mais quand j'essaie de trier ça i Obtenez des exceptions: p>

J'utilise les versions suivantes de: p> xxx pré>

le code Java comme suit: p>

[2014-03-20 13:37:02,720][DEBUG][action.search.type       ] [Smuggler II] [210a9696a28545f2bbeecf88d64fbad8_20140318_153743][4], node[dB9dCIXMRZGmdUExquMWlQ], [P], s[STARTED]: Failed to execute [org.elasticsearch.action.search.SearchRequest@71b978fe] lastShard [true]
org.elasticsearch.search.SearchParseException: [210a9696a28545f2bbeecf88d64fbad8_20140318_153743][4]: query[ConstantScore(*:*)],from[0],size[-1]: Parse Failure [Failed to parse source [{"from":0,"query":{"match_all":{}},"post_filter":{"geo_distance":{"location":[-2.217753,53.432703],"distance":"10km"}},"sort":[{"location":{"order":"asc"}}]}]]
    at org.elasticsearch.search.SearchService.parseSource(SearchService.java:595)
    at org.elasticsearch.search.SearchService.createContext(SearchService.java:498)
    at org.elasticsearch.search.SearchService.createAndPutContext(SearchService.java:472)
    at org.elasticsearch.search.SearchService.executeDfsPhase(SearchService.java:178)
    at org.elasticsearch.search.action.SearchServiceTransportAction.sendExecuteDfs(SearchServiceTransportAction.java:168)
    at org.elasticsearch.action.search.type.TransportSearchDfsQueryThenFetchAction$AsyncAction.sendExecuteFirstPhase(TransportSearchDfsQueryThenFetchAction.java:85)
    at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.performFirstPhase(TransportSearchTypeAction.java:216)
    at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.performFirstPhase(TransportSearchTypeAction.java:203)
    at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction$2.run(TransportSearchTypeAction.java:186)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:701)
Caused by: org.elasticsearch.ElasticsearchIllegalArgumentException: can't sort on geo_point field without using specific sorting feature, like geo_distance
    at org.elasticsearch.index.fielddata.plain.AbstractGeoPointIndexFieldData.comparatorSource(AbstractGeoPointIndexFieldData.java:142)
    at org.elasticsearch.search.sort.SortParseElement.addSortField(SortParseElement.java:222)
    at org.elasticsearch.search.sort.SortParseElement.addCompoundSortField(SortParseElement.java:172)
    at org.elasticsearch.search.sort.SortParseElement.parse(SortParseElement.java:80)
    at org.elasticsearch.search.SearchService.parseSource(SearchService.java:583)
    ... 11 more
[2014-03-20 13:37:02,722][DEBUG][action.search.type       ] [Smuggler II] All shards failed for phase: [dfs]


0 commentaires

3 Réponses :


8
votes

Juste au cas où quelqu'un d'autre ayant le même problème, nous avons résolu notre problème de tri de la manière suivante:

public List<SiteResource> findByGeoLocation(Double longitude, Double latitude, String channelKey, Double distance) {

        if(StringUtils.isEmpty(distance)){
            distance = defaultRadius;           
        }

        GeoDistanceFilterBuilder filter = FilterBuilders.geoDistanceFilter("location").point(latitude, longitude).distance(distance, DistanceUnit.KILOMETERS);

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withFilter(filter)
                .withSort(SortBuilders.geoDistanceSort("site.location").point(latitude, longitude).order(SortOrder.ASC)).build();

        searchQuery.addIndices(channelKey);
        searchQuery.addTypes("site");

        List<SiteResource> sites = esTemplate.queryForList(searchQuery, com.company.domain.site.SiteResource.class);
        return sites;
    }


2 commentaires

En passant, vous n'avez pas besoin de définir la version élastiquesarch car elle viendra une dépendance transitoire des données de printemps élastiquesarch.


vous avez raison, je viens de supprimer cela de la question



0
votes

La réponse, à partir de @justme, a aidé à trouver la dernière possibilité d'atteindre la recherche Geo Distance. Comme les filtres et les requêtes ont été fusionnés, nous pouvons plutôt utiliser des querybuilders.

C'est ainsi que j'ai atteint les résultats (triés et paginé): xxx

"geopoint" -> le Field géopoint en entité élastiquearch.


0 commentaires

0
votes

Très tard sur le jeu, mais depuis le printemps Data Elasticssearch 4.0, publié la semaine dernière, il est possible de définir un géodistance pour un Trier qui peut être transmis à une méthode de référentiel.

Les valeurs de distance du résultat de la recherche peuvent être lues à partir de l'objet searchhit renvoyé.

i Un article de blog montrer comment faire cela dans les détails


1 commentaires

PJ, cet article a l'air super, laissez-moi essayer :)