Nest (Geo)Location 的经度始终为 0?
Nest (Geo)Location's Longitude is always 0?
我一直在深入研究将 NEST 用于基于 .Net 的项目,该项目将使用 ElasticSearch,但让我一直困惑的是 GeoDistance 查询从未返回任何结果。
调试简单“*”查询的响应并查看搜索结果的 .Documents 时,所有文档实例的经度值为 0.0 - 但纬度是正确的。
这是一个最新鲜的基本 ES 服务器(下载并 运行),没有任何(重新)配置。与 FacetFlow 托管的服务器相同。
版本方面,Elasticsearch.Net是1.4.3,NEST也是,ElasticSearch本身是1.4.4版本。
这里有什么我遗漏的吗?或者更准确地说,我在这里遗漏了什么?
示例代码如下所示(下面使用的GeoLocationclass就是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
class.
所以你的 Post
class 应该是这样的:
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
因为你想在你的 GeoDistanceFilter
.
中使用 GeoOptimizeBBox.Indexed
索引的 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)))
);
希望这对您有所帮助:)
我一直在深入研究将 NEST 用于基于 .Net 的项目,该项目将使用 ElasticSearch,但让我一直困惑的是 GeoDistance 查询从未返回任何结果。
调试简单“*”查询的响应并查看搜索结果的 .Documents 时,所有文档实例的经度值为 0.0 - 但纬度是正确的。
这是一个最新鲜的基本 ES 服务器(下载并 运行),没有任何(重新)配置。与 FacetFlow 托管的服务器相同。
版本方面,Elasticsearch.Net是1.4.3,NEST也是,ElasticSearch本身是1.4.4版本。
这里有什么我遗漏的吗?或者更准确地说,我在这里遗漏了什么?
示例代码如下所示(下面使用的GeoLocationclass就是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
class.
所以你的 Post
class 应该是这样的:
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
因为你想在你的 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)))
);
希望这对您有所帮助:)