Elasticsearch 2.3中基于地理距离的排序停止工作

时间:2016-07-05 06:08:35

标签: elasticsearch

我已根据其位置在Elasticsearch中实现了对用户的搜索和排序。它曾经在Elasticsearch 1.6中运行良好,但在升级到Elasticsearch 2.3.3之后它就停止了工作。

这是我在ES中的映射:

{
"user": {
    "properties": {
        "id": {
            "store": false,
            "type": "long"
        },
        "url": {
            "store": false,
            "type": "string"
        },
        "name": {
            "store": false,
            "type": "string"
        },
        "lastname": {
            "store": false,
            "type": "string"
        },
        "system": {
            "store": false,
            "type": "boolean"
        },
        "avatar": {
            "store": false,
            "type": "string"
        },

        "position": {
            "store": false,
            "type": "string"
        },

        "location": {
            "type": "geo_point"
        },


        "roles": {
            "properties": {
                "id": {
                    "store": false,
                    "type": "long"
                }
            }
        },

        "credentials": {
            "type": "nested",
            "properties": {
                "id": {
                    "store": false,
                    "type": "long"
                },
                "progress": {
                    "store": false,
                    "type": "integer"
                },
                "instructorId": {
                    "store": false,
                    "type": "long"
                },
                "dateEnrolled":{
                    "store": false,
                    "type":"date",
                    "format":"yyyy/MM/dd HH:mm:ss"
                }
            }
        },
        "credentialsWithInstructorRole": {
            "properties": {
                "id": {
                    "store": false,
                    "type": "long"
                },
                "dateAssigned":{
                    "store": false,
                    "type":"date",
                    "format":"yyyy/MM/dd HH:mm:ss"
                }
            }
        }
    }
}

}

当我尝试直接执行以下查询时,它可以正常工作:

[
      {
        "from": 0,
        "size": 3,
        "query": {
          "bool": {
        "must_not": {
          "term": {
            "id": 2
          }
        },
        "should": {
          "match_all": {}
        }
          }
        },
        "sort": [
          {
        "_geo_distance": {
          "user.location": [
            {
              "lat": 49.2827291,
              "lon": -123.12073750000002
            }
          ],
          "unit": "km"
        }
          }
        ]
      }
    ]

但是,使用Java API执行相同的查询时,会出现异常:

Failed to execute phase [query], all shards failed; shardFailures {[G88txaRXQESUgytUEnTwug][users_zj][0]: RemoteTransportException[[Living Colossus][127.0.0.1:9300][indices:data/read/search[phase/query]]]; nested: SearchParseException[failed to parse search source [{"from":0,"size":3,"query":{"bool":{"must_not":{"term":{"id":2}},"should":{"match_all":{}}}},"sort":[{"_geo_distance":{"user.location":[{"lat":49.2827291,"lon":-123.12073750000002}],"unit":"km"}}]}]]; nested: IllegalArgumentException[failed to find mapper for [user.location] for geo distance based sort]; }{[G88txaRXQESUgytUEnTwug][users_zj][1]: RemoteTransportException[[Living Colossus][127.0.0.1:9300][indices:data/read/search[phase/query]]]; nested: SearchParseException[failed to parse search source [{"from":0,"size":3,"query":{"bool":{"must_not":{"term":{"id":2}},"should":{"match_all":{}}}},"sort":[{"_geo_distance":{"user.location":[{"lat":49.2827291,"lon":-123.12073750000002}],"unit":"km"}}]}]]; nested: IllegalArgumentException[failed to find mapper for [user.location] for geo distance based sort]; }{[G88txaRXQESUgytUEnTwug][users_zj][2]: RemoteTransportException[[Living Colossus][127.0.0.1:9300][indices:data/read/search[phase/query]]]; nested: SearchParseException[failed to parse search source [{"from":0,"size":3,"query":{"bool":{"must_not":{"term":{"id":2}},"should":{"match_all":{}}}},"sort":[{"_geo_distance":{"user.location":[{"lat":49.2827291,"lon":-123.12073750000002}],"unit":"km"}}]}]]; nested: IllegalArgumentException[failed to find mapper for [user.location] for geo distance based sort]; }{[G88txaRXQESUgytUEnTwug][users_zj][3]: RemoteTransportException[[Living Colossus][127.0.0.1:9300][indices:data/read/search[phase/query]]]; nested: SearchParseException[failed to parse search source [{"from":0,"size":3,"query":{"bool":{"must_not":{"term":{"id":2}},"should":{"match_all":{}}}},"sort":[{"_geo_distance":{"user.location":[{"lat":49.2827291,"lon":-123.12073750000002}],"unit":"km"}}]}]]; nested: IllegalArgumentException[failed to find mapper for [user.location] for geo distance based sort]; }{[G88txaRXQESUgytUEnTwug][users_zj][4]: RemoteTransportException[[Living Colossus][127.0.0.1:9300][indices:data/read/search[phase/query]]]; nested: SearchParseException[failed to parse search source [{"from":0,"size":3,"query":{"bool":{"must_not":{"term":{"id":2}},"should":{"match_all":{}}}},"sort":[{"_geo_distance":{"user.location":[{"lat":49.2827291,"lon":-123.12073750000002}],"unit":"km"}}]}]]; nested: IllegalArgumentException[failed to find mapper for [user.location] for geo distance based sort]; }
        at org.elasticsearch.action.search.AbstractSearchAsyncAction.onFirstPhaseResult(AbstractSearchAsyncAction.java:206)
        at org.elasticsearch.action.search.AbstractSearchAsyncAction$1.onFailure(AbstractSearchAsyncAction.java:152)
        at org.elasticsearch.action.ActionListenerResponseHandler.handleException(ActionListenerResponseHandler.java:46)
        at org.elasticsearch.transport.TransportService$DirectResponseChannel.processException(TransportService.java:855)
        at org.elasticsearch.transport.TransportService$DirectResponseChannel.sendResponse(TransportService.java:833)
        at org.elasticsearch.transport.TransportService$4.onFailure(TransportService.java:387)
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:39)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: NotSerializableExceptionWrapper[: failed to find mapper for [user.location] for geo distance based sort]; nested: IllegalArgumentException[failed to find mapper for [user.location] for geo distance based sort];
        at org.elasticsearch.ElasticsearchException.guessRootCauses(ElasticsearchException.java:386)
        at org.elasticsearch.action.search.SearchPhaseExecutionException.guessRootCauses(SearchPhaseExecutionException.java:152)
        at org.elasticsearch.action.search.SearchPhaseExecutionException.getCause(SearchPhaseExecutionException.java:99)
        at org.elasticsearch.ElasticsearchException.writeTo(ElasticsearchException.java:226)
        at org.elasticsearch.action.search.SearchPhaseExecutionException.writeTo(SearchPhaseExecutionException.java:64)
        at org.elasticsearch.common.io.stream.StreamOutput.writeThrowable(StreamOutput.java:564)
        at org.elasticsearch.ElasticsearchException.writeTo(ElasticsearchException.java:226)
        at org.elasticsearch.transport.ActionTransportException.writeTo(ActionTransportException.java:64)
        at org.elasticsearch.common.io.stream.StreamOutput.writeThrowable(StreamOutput.java:564)
        at org.elasticsearch.transport.netty.NettyTransportChannel.sendResponse(NettyTransportChannel.java:120)
        at org.elasticsearch.transport.DelegatingTransportChannel.sendResponse(DelegatingTransportChannel.java:68)
        at org.elasticsearch.transport.RequestHandlerRegistry$TransportChannelWrapper.sendResponse(RequestHandlerRegistry.java:146)
        at org.elasticsearch.action.support.HandledTransportAction$TransportHandler$1.onFailure(HandledTransportAction.java:74)
        at org.elasticsearch.action.search.AbstractSearchAsyncAction.raiseEarlyFailure(AbstractSearchAsyncAction.java:294)
        ... 10 more
    Caused by: java.lang.IllegalArgumentException: failed to find mapper for [user.location] for geo distance based sort
        at org.elasticsearch.search.sort.GeoDistanceSortParser.parse(GeoDistanceSortParser.java:161)
        at org.elasticsearch.search.sort.SortParseElement.addCompoundSortField(SortParseElement.java:141)
        at org.elasticsearch.search.sort.SortParseElement.parse(SortParseElement.java:84)
        at org.elasticsearch.search.SearchService.parseSource(SearchService.java:838)
        at org.elasticsearch.search.SearchService.createContext(SearchService.java:654)
        at org.elasticsearch.search.SearchService.createAndPutContext(SearchService.java:620)
        at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:371)
        at org.elasticsearch.search.action.SearchServiceTransportAction$SearchQueryTransportHandler.messageReceived(SearchServiceTransportAction.java:368)
        at org.elasticsearch.search.action.SearchServiceTransportAction$SearchQueryTransportHandler.messageReceived(SearchServiceTransportAction.java:365)
        at org.elasticsearch.transport.TransportRequestHandler.messageReceived(TransportRequestHandler.java:33)
        at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:75)
        at org.elasticsearch.transport.TransportService$4.doRun(TransportService.java:376)
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
        ... 3 more

这是触发异常的java方法:

    @Override
public List<User> getCollaboratorsBasedOnLocation(Collection<User> ignoredUsers, double lat, double lon, int limit){
    List<User> foundUsers = new ArrayList<User>();
    try {
        Client client = ElasticSearchFactory.getClient();
        QueryBuilder qb = new MatchAllQueryBuilder();
        BoolQueryBuilder bQueryBuilder = QueryBuilders.boolQuery();
        bQueryBuilder.should(qb);

        for (User ignUser : ignoredUsers) {
            if (ignUser != null) {
                bQueryBuilder.mustNot(termQuery("id", ignUser.getId()));
            }
        }
        GeoDistanceSortBuilder sortBuilder = SortBuilders.geoDistanceSort("user.location")
                .point(lat, lon)
                .unit(DistanceUnit.KILOMETERS)
                .order(SortOrder.ASC);

        SearchResponse sResponse = client
                .prepareSearch(ESIndexNames.INDEX_USERS)
                .setTypes(ESIndexTypes.USER)
                .setQuery(bQueryBuilder)
                .addSort(sortBuilder)
                .setFrom(0)
                .setSize(limit)
                .execute()
                .actionGet();

        foundUsers = this.convertSearchResponseToUsersList(sResponse);
    } catch (NoNodeAvailableException e1) {
        logger.error(e1);
    }
    return foundUsers;
}

解决方案

事实证明问题出在算法的排序部分的路径中。这是不正确的,并在更改&#34; user.location&#34;到&#34;位置&#34;一切都恢复正常。

0 个答案:

没有答案