.net - Nest (Geo)Location 的经度始终为 0?

标签 .net elasticsearch nest elasticsearch-net

我一直在深入研究如何将 NEST 用于基于 .Net 的项目,该项目将利用 ElasticSearch,但一直让我困惑的是 GeoDistance 查询从未返回任何结果。

在调试简单“*”查询的响应并查看搜索结果的 .Documents 时,所有文档实例的经度值为 0.0 - 但纬度是正确的值。

这是一个基本的 ES 服务器,与它一样新鲜(下载并运行),没有任何(重新)配置......与 FacetFlow 托管的服务器相同。

至于版本,Elasticsearch.Net是1.4.3,NEST也是,ElasticSearch本身是1.4.4版本。

我在这里缺少什么,或者更准确地说 - 我在这里缺少什么?

示例代码如下所示(下面使用的 GeoLocation 类是 Nest.GeoLocation 类):

using System;
using System.Linq;
using Nest;

namespace NestPlayground
{
    public class Post
    {
        public Guid Id { get; set; }
        public string User { get; set; }
        public DateTime CreatedAt { get; set; }
        public string Message { get; set; }
        public GeoLocation Location { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var indexName = "sampleindex";

            var uri = new Uri("<elasticsearch url>");
            var settings = new ConnectionSettings(uri).SetDefaultIndex(indexName);
            var client = new ElasticClient(settings);

            client.DeleteIndex(indexName);

            var post = new Post
            {
                Id = Guid.NewGuid(),
                User = "Some User",
                CreatedAt = DateTime.UtcNow,
                Message = "Some Sample Message",
                Location = new GeoLocation(37.809860, -122.476995)
            };

            client.Index(post);
            client.Refresh();

            // Execute a search using the connection from above.

            var result = client.Search<Post>(s => s
                               .Index(indexName)
                               .Query(queryDescriptor => queryDescriptor.QueryString(queryStringQueryDescriptor => queryStringQueryDescriptor.Query("*")))
                               //.Filter(filterDescriptor => filterDescriptor.GeoDistance(post1 => post1.Location, geoDistanceFilterDescriptor => geoDistanceFilterDescriptor
                               //    .Distance(50, GeoUnit.Kilometers)
                               //    .Location(Lat: 37.802774, Lon: -122.4478561)
                               //    .Optimize(GeoOptimizeBBox.Indexed)))
                               );

            // this DOES return the just created/indexed document, but its .Longitude / result.Documents.First().Location.Longtitude property is always '0'?!
        }
    }
}

最佳答案

1. 看起来 GeoLocation 类型已过时。甚至是NEST tests使用 CustomGeoLocation 类。

所以你的 Post 类应该如下所示:

public class Post
{
    public Guid Id { get; set; }
    public string User { get; set; }
    public DateTime CreatedAt { get; set; }
    public string Message { get; set; }
    [ElasticProperty(Type = FieldType.GeoPoint)]
    public Location Location { get; set; }
}

public class Location
{
    public Location(double lat, double lon)
    {
        Lat = lat;
        Lon = lon;
    }

    public double Lat { get; set; }
    public double Lon { get; set; }
}

2. Geo Distance Filter 的文档说:

The filter requires the geo_point type to be set on the relevant field.

这就是我将 Location 类型设置为 FieldType.GeoPoint 的原因。

记住为您的索引创建映射。

client.CreateIndex(
    descriptor =>
        descriptor.Index(indexName)
            .AddMapping<Post>(
                m => m.Properties(p => p
                    .GeoPoint(mappingDescriptor => mappingDescriptor.Name(f => f.Location).IndexLatLon()))));

我打开了 lat_lon 因为您想使用 GeoOptimizeBBox.Indexed在您的 GeoDistanceFilter 中。

索引的 ES 映射:

{
    "sampleindex" : {
        "mappings" : {
            "post" : {
                "properties" : {
                    "createdAt" : {
                        "type" : "date",
                        "format" : "dateOptionalTime"
                    },
                    "id" : {
                        "type" : "string"
                    },
                    "location" : {
                        "type" : "geo_point",
                        "lat_lon" : true
                    },
                    "message" : {
                        "type" : "string"
                    },
                    "user" : {
                        "type" : "string"
                    }
                }
            }
        }
    }
}

3. 现在这个查询终于可以工作了

var result = client.Search<Post>(s => s
    .Index(indexName)
    .Query(
        queryDescriptor => queryDescriptor.QueryString(queryStringQueryDescriptor => queryStringQueryDescriptor.Query("*")))
    .Filter(
        filterDescriptor =>
            filterDescriptor.GeoDistance(post1 => post1.Location, geoDistanceFilterDescriptor => geoDistanceFilterDescriptor
                .Distance(500, GeoUnit.Kilometers)
                .Location(37.802774, -122.4478561)
                .Optimize(GeoOptimizeBBox.Indexed)))
    );

希望这有帮助:)

关于.net - Nest (Geo)Location 的经度始终为 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29332016/

相关文章:

elasticsearch - Elasticsearch在删除索引时触发refresh_mappings

elasticsearch - 根据上次索引时间在查询时间提升 Elasticsearch 结果

elasticsearch - 如何使用Elasticsearch对输入的文本执行部分单词搜索?

elasticsearch - ElasticSearch NEST多重匹配返回所有结果

c# - 将一个数字加密为另一个相同长度的数字

c# - 在 Alea.GPU 中传递超过 16 个内核参数

python - Elasticsearch 在 python 中更新文档

elasticsearch - 嵌套查询在 bool 中写入必须和应该

.net - Azure 中的 ASP.Net 应用程序缓存

c# - MVVM 模式困惑