Search code examples
c#asp.net-coreelasticsearchsyntaxnest

Error while sorting with NEST (unknown field ignore_unmapped)


I am getting this error ([field_sort] unknown field [ignore_unmapped]) when sorting with NEST. The reason is in this place, if you comment then everything is ok. Please help me understand this issue.

internal static void SortBy(string sortColumn, string sortType, SearchDescriptor<BaseIndexerObject> searchDescriptor)

        {
            Action<string, string, SearchDescriptor<BaseIndexerObject>> algorithm;
            bool algorithmExists = sortAlgorithms.TryGetValue(sortColumn, out algorithm);
            if (algorithmExists)
            {
                algorithm(sortColumn, sortType, searchDescriptor);
                return;
            }

            searchDescriptor.Sort(sortFieldDescriptor =>
            {
                if (sortType == "asc")
                {
                    sortFieldDescriptor.Ascending(asc => sortColumn);
                }
                else
                {
                    sortFieldDescriptor.Descending(desc => sortColumn);
                }

                ParameterExpression param = Expression.Parameter(typeof(BaseIndexerObject), "x");
                Expression<Func<BaseIndexerObject, object>> lambda =
                    Expression.Lambda<Func<BaseIndexerObject, object>>(
                        Expression.Convert(Expression.PropertyOrField(param, sortColumn), typeof(object)), param);

                sortFieldDescriptor.Field(f => f.Field(lambda).IgnoreUnmappedFields());

                return sortFieldDescriptor;
            });
        }

Generated request and error response

POST http://XXX.XXX.XX.XXX:9200/object_folder666_%2A%2Cobject_folder777_%2A/_search?pretty=true&error_trace=true&typed_keys=true HTTP/1.1
Accept: application/json
Content-Type: application/json
User-Agent: elasticsearch-net/7.9.0+54ddce9e1b7e7f755e185f4f6431948fee95e1b9 (Microsoft Windows 10.0.18363; .NET Framework 4.8.4250.0; Nest)
Host: XXX.XXX.XX.XXX:9200
Content-Length: 828

{"from":0,"highlight":{"encoder":"html","fields":{"*":{}},"post_tags":["</mark>"],"pre_tags":["<mark>"]},"query":{"bool":{"must":[{"bool":{"must":[{"bool":{"filter":[{"query_string":{"default_operator":"and","query":"*"}}]}},{"range":{"74":{"gte":0.0,"lte":2147483647.0}}},{"match_all":{}},{"match_all":{}}],"must_not":[{"term":{"79":{"value":300}}},{"bool":{"must":[{"term":{"79":{"value":257}}}],"must_not":[{"term":{"4239":{"value":0}}}]}}]}},{"bool":{"should":[{"bool":{"must":[{"match_all":{}},{"match_all":{}}]}},{"nested":{"path":"12416","query":{"bool":{"must":[{"match_all":{}},{"match_all":{}}]}}}}]}},{"match_all":{}},{"match_all":{}},{"match_all":{}},{"match_all":{}},{"terms":{"833":[-1]}},{"match_all":{}}]}},"size":5,"sort":[{"sortColumn":{"order":"desc"}},{"TimeReal":{"ignore_unmapped":true}}],"timeout":"360s"}


HTTP/1.1 400 Bad Request
content-type: application/json; charset=UTF-8
content-length: 14644

{
  "error" : {
    "root_cause" : [
      {
        "type" : "x_content_parse_exception",
        "reason" : "[1:786] [field_sort] unknown field [ignore_unmapped]",
        "stack_trace" : "[[1:786] [field_sort] unknown field [ignore_unmapped]]; nested: XContentParseException[[1:786] [field_sort] unknown field [ignore_unmapped]];\n\tat org.elasticsearch.ElasticsearchException.guessRootCauses(ElasticsearchException.java:644)\n\tat org.elasticsearch.ElasticsearchException.generateFailureXContent(ElasticsearchException.java:572)\n\tat org.elasticsearch.rest.BytesRestResponse.build(BytesRestResponse.java:149)\n\tat org.elasticsearch.rest.BytesRestResponse.<init>(BytesRestResponse.java:110)\n\tat org.elasticsearch.rest.BytesRestResponse.<init>(BytesRestResponse.java:93)\n\tat org.elasticsearch.rest.RestController.dispatchRequest(RestController.java:238)\n\tat org.elasticsearch.rest.RestController.tryAllHandlers(RestController.java:318)\n\tat org.elasticsearch.rest.RestController.dispatchRequest(RestController.java:176)\n\tat org.elasticsearch.http.AbstractHttpServerTransport.dispatchRequest(AbstractHttpServerTransport.java:318)\n\tat org.elasticsearch.http.AbstractHttpServerTransport.handleIncomingRequest(AbstractHttpServerTransport.java:372)\n\tat org.elasticsearch.http.AbstractHttpServerTransport.incomingRequest(AbstractHttpServerTransport.java:308)\n\tat org.elasticsearch.http.netty4.Netty4HttpRequestHandler.channelRead0(Netty4HttpRequestHandler.java:42)\n\tat org.elasticsearch.http.netty4.Netty4HttpRequestHandler.channelRead0(Netty4HttpRequestHandler.java:28)\n\tat io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat org.elasticsearch.http.netty4.Netty4HttpPipeliningHandler.channelRead(Netty4HttpPipeliningHandler.java:58)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)\n\tat io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)\n\tat io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)\n\tat io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:615)\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:578)\n\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)\n\tat io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)\n\tat io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)\n\tat java.base/java.lang.Thread.run(Thread.java:832)\nCaused by: org.elasticsearch.common.xcontent.XContentParseException: [1:786] [field_sort] unknown field [ignore_unmapped]\n\tat org.elasticsearch.common.xcontent.ObjectParser.lambda$errorOnUnknown$2(ObjectParser.java:102)\n\tat org.elasticsearch.common.xcontent.ObjectParser.parse(ObjectParser.java:297)\n\tat org.elasticsearch.search.sort.FieldSortBuilder.fromXContent(FieldSortBuilder.java:690)\n\tat org.elasticsearch.search.sort.SortBuilder.parseCompoundSortField(SortBuilder.java:148)\n\tat org.elasticsearch.search.sort.SortBuilder.fromXContent(SortBuilder.java:106)\n\tat org.elasticsearch.search.builder.SearchSourceBuilder.parseXContent(SearchSourceBuilder.java:1170)\n\tat org.elasticsearch.rest.action.search.RestSearchAction.parseSearchRequest(RestSearchAction.java:137)\n\tat org.elasticsearch.rest.action.search.RestSearchAction.lambda$prepareRequest$1(RestSearchAction.java:113)\n\tat org.elasticsearch.rest.RestRequest.withContentOrSourceParamParserOrNull(RestRequest.java:470)\n\tat org.elasticsearch.rest.action.search.RestSearchAction.prepareRequest(RestSearchAction.java:112)\n\tat org.elasticsearch.rest.BaseRestHandler.handleRequest(BaseRestHandler.java:94)\n\tat org.elasticsearch.xpack.security.rest.SecurityRestFilter.handleRequest(SecurityRestFilter.java:81)\n\tat org.elasticsearch.rest.RestController.dispatchRequest(RestController.java:236)\n\t... 53 more\n"
      }
    ],
    "type" : "x_content_parse_exception",
    "reason" : "[1:786] [field_sort] unknown field [ignore_unmapped]",
    "stack_trace" : "org.elasticsearch.common.xcontent.XContentParseException: [1:786] [field_sort] unknown field [ignore_unmapped]\n\tat org.elasticsearch.common.xcontent.ObjectParser.lambda$errorOnUnknown$2(ObjectParser.java:102)\n\tat org.elasticsearch.common.xcontent.ObjectParser.parse(ObjectParser.java:297)\n\tat org.elasticsearch.search.sort.FieldSortBuilder.fromXContent(FieldSortBuilder.java:690)\n\tat org.elasticsearch.search.sort.SortBuilder.parseCompoundSortField(SortBuilder.java:148)\n\tat org.elasticsearch.search.sort.SortBuilder.fromXContent(SortBuilder.java:106)\n\tat org.elasticsearch.search.builder.SearchSourceBuilder.parseXContent(SearchSourceBuilder.java:1170)\n\tat org.elasticsearch.rest.action.search.RestSearchAction.parseSearchRequest(RestSearchAction.java:137)\n\tat org.elasticsearch.rest.action.search.RestSearchAction.lambda$prepareRequest$1(RestSearchAction.java:113)\n\tat org.elasticsearch.rest.RestRequest.withContentOrSourceParamParserOrNull(RestRequest.java:470)\n\tat org.elasticsearch.rest.action.search.RestSearchAction.prepareRequest(RestSearchAction.java:112)\n\tat org.elasticsearch.rest.BaseRestHandler.handleRequest(BaseRestHandler.java:94)\n\tat org.elasticsearch.xpack.security.rest.SecurityRestFilter.handleRequest(SecurityRestFilter.java:81)\n\tat org.elasticsearch.rest.RestController.dispatchRequest(RestController.java:236)\n\tat org.elasticsearch.rest.RestController.tryAllHandlers(RestController.java:318)\n\tat org.elasticsearch.rest.RestController.dispatchRequest(RestController.java:176)\n\tat org.elasticsearch.http.AbstractHttpServerTransport.dispatchRequest(AbstractHttpServerTransport.java:318)\n\tat org.elasticsearch.http.AbstractHttpServerTransport.handleIncomingRequest(AbstractHttpServerTransport.java:372)\n\tat org.elasticsearch.http.AbstractHttpServerTransport.incomingRequest(AbstractHttpServerTransport.java:308)\n\tat org.elasticsearch.http.netty4.Netty4HttpRequestHandler.channelRead0(Netty4HttpRequestHandler.java:42)\n\tat org.elasticsearch.http.netty4.Netty4HttpRequestHandler.channelRead0(Netty4HttpRequestHandler.java:28)\n\tat io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat org.elasticsearch.http.netty4.Netty4HttpPipeliningHandler.channelRead(Netty4HttpPipeliningHandler.java:58)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)\n\tat io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)\n\tat io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\n\tat io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\n\tat io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)\n\tat io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:615)\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:578)\n\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)\n\tat io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)\n\tat io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)\n\tat java.base/java.lang.Thread.run(Thread.java:832)\n"
  },
  "status" : 400
}

Under RFC2616, HTTP/400 responses will not be cached regardless of what caching headers may be present. This response does not specify explicit HTTP Cache Lifetime information and does not specify a Last-Modified date. Heuristic expiration is typically based on Last-Modified date. Lacking Last-Modified, this response may be revalidated on every use or once per browsing session, depending on the browser configuration.

This response contains neither an ETAG nor a Last-Modified time. This will prevent a Conditional Revalidation of this response.

enter image description here enter image description here


Solution

  • It's not completely clear to me what the intentions of the query are, but ignore_unmapped looks like it's only supported with geo distance sorting.

    With other field sorting, the unmapped_type property can be used. I think you're looking for something like the following

    private static void Main()
    {
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    
        var defaultIndex = "posts";
        var settings = new ConnectionSettings(pool)
            .DefaultIndex(defaultIndex);
            
        var client = new ElasticClient(settings);
    
        var sortType = "asc";
        var sortColumn = "TimeReal";
    
        var response = client.Search<Post>(s => s
            .Sort(sortFieldDescriptor =>
                {
                    // TODO: probably cache/source generate the mapping of PropertyInfo -> FieldType
                    var property = typeof(BaseIndexerObject).GetProperty(sortColumn);
                    FieldType? unmappedType = null;
                    
                    switch (property.PropertyType.FullName)
                    {
                        case "System.Int32":
                            unmappedType = FieldType.Integer;
                            break;
                        // TODO: fill in other relevant Type -> FieldType mappings
                    }
                    
                    sortFieldDescriptor.Field(f => f
                        .Field(sortColumn)
                        .UnmappedType(unmappedType)
                        .Order(sortType == "asc" ? SortOrder.Ascending : SortOrder.Descending)
                    );
    
                    return sortFieldDescriptor;
                })
        );
    }
    
    public class BaseIndexerObject
    {
        public int TimeReal { get; set; }
    }
    

    which generates the query

    POST http://localhost:9200/posts/_search?pretty=true&typed_keys=true 
    {
      "sort": [
        {
          "TimeReal": {
            "unmapped_type": "integer",
            "order": "asc"
          }
        }
      ]
    }
    

    (An aside, I would take a look at the code used to generate queries. There's a lot of superfluous match_all queries in what is generated that will unnecessarily complicate query parsing on the server).