Elasticsearch按地理位置排序无经纬度时触发空引用异常求助
解决Nest中GeoDistance排序的NullReferenceException问题
你遇到的问题根源很明确:当searchAjaxRequest.location为空,或者它的lat/lon是null时,你返回的SortGeoDistanceDescriptor没有设置对应的字段(Field(ab =>ab.location)这一步没执行),Nest在序列化排序条件的时候,内部的FieldResolver找不到有效的字段引用,直接抛出了空引用异常。
修复方案
核心思路是仅当地理位置参数有效时,才添加GeoDistance排序规则,而不是不管参数是否合法都强行加入一个未配置完整的排序项。我们可以把Sort的构建逻辑拆解开,通过条件判断来决定是否追加GeoDistance排序:
// 先构建基础排序部分 var sortDescriptor = new SortDescriptor<CarSearchRequest>() .Ascending(fs => fs.current_stage); // 处理自定义排序规则 if (searchAjaxRequest.sortingFilter != null) { switch (searchAjaxRequest.sortingFilter.ToLower()) // 统一转小写避免大小写匹配问题 { case "titleasc": sortDescriptor.Field(tt => tt.model, SortOrder.Ascending); break; case "titledsc": sortDescriptor.Field(tt => tt.model, SortOrder.Descending); break; case "priceasc": sortDescriptor.Field(tt => tt.price, SortOrder.Ascending); break; case "pricedsc": sortDescriptor.Field(tt => tt.price, SortOrder.Descending); break; case "kmasc": sortDescriptor.Field(tt => tt.kmRun, SortOrder.Ascending); break; case "kmdsc": sortDescriptor.Field(tt => tt.kmRun, SortOrder.Descending); break; case "introductiondateasc": sortDescriptor.Field(tt => tt.mfYear, SortOrder.Ascending); break; case "introductiondatedesc": sortDescriptor.Field(tt => tt.mfYear, SortOrder.Descending); break; } } else if (searchAjaxRequest.category != null) { switch (searchAjaxRequest.category) { case "recentViewed": sortDescriptor.Field(tt => tt.createdDate, SortOrder.Descending); break; case "topRated": sortDescriptor.Field(tt => tt.overallRating, SortOrder.Descending); break; } } // 仅当location参数完整有效时,添加GeoDistance排序 if (searchAjaxRequest.location != null && searchAjaxRequest.location.lat.HasValue && searchAjaxRequest.location.lon.HasValue) { sortDescriptor.GeoDistance(g => g .Field(ab => ab.location) .Order(SortOrder.Ascending) .Unit(DistanceUnit.Kilometers) .Mode(SortMode.Min) .Points(new GeoLocation(searchAjaxRequest.location.lat.Value, searchAjaxRequest.location.lon.Value)) ); } // 将构建好的排序描述符传入查询 .Sort(sortDescriptor)
为什么这样能解决问题?
原来的代码不管location是否有效,都会返回一个SortGeoDistanceDescriptor对象,哪怕这个对象没有设置Field。Nest在序列化这个空的描述符时,会尝试解析字段引用,结果因为字段未设置而触发空引用异常。
重构后的代码只有在location及其lat/lon都不为空时,才会添加GeoDistance排序项。如果参数无效,这部分排序规则就不会被加入到Sort集合中,从根本上避免了无效排序条件的序列化问题。
额外优化建议
你可以再增加对经纬度数值合法性的检查(比如lat范围在-90到90之间,lon范围在-180到180之间),确保地理位置参数是有效的,再执行排序逻辑,进一步提升代码健壮性。
内容的提问来源于stack exchange,提问作者Surendra Singh
相关产品推荐
相关产品推荐

