NEST API GeoShapes字段的默认值 [英] NEST API Default value for GeoShapes fields
问题描述
我们正在使用以下过滤器:
filters.Add(fq => fq.Term(t => t.Field(f => f.LocalityId).Value(locationParams [2]))||q.GeoShape(g => g.Field("locationShape").Relation(GeoShapeRelation.Inner).IndexedShape(f => f.Id(searchCriteria.spLocationId).Index(indexName).Path("geometry"))));
但是,如果缺少 geometry 字段,Elasticsearch会引发异常.
无论如何,通过在映射中使用默认值(空值)或任何其他方式来避免这种情况.
在这种情况下,无法避免该异常.Elasticsearch假定用户提供给预索引形状的参数有效.
理想地,应以防止最终用户提供无效值的方式约束提供给索引形状的值.如果那不可行,则可以在 indexName
exists 查询和 ids
查询的过滤子句的 bool
查询>索引,然后将索引形状的几何形状查询过滤器添加到搜索请求中.
例如
私有静态void Main(){var documentIndex =文件";varshapesIndex ="shapes";var host ="localhost";var pool = new SingleNodeConnectionPool(new Uri($"http://{host}:9200"));var settings = new ConnectionSettings(pool).DefaultMappingFor< Document>(m => m.IndexName(documentsIndex)).DefaultMappingFor< Shape>(m => m.IndexName(shapesIndex));var client = new ElasticClient(settings);如果(client.Indices.Exists(documentsIndex).Exists)client.Indices.Delete(documentsIndex);client.Indices.Create(documentsIndex,c => c.Map< Document>(m => m.AutoMap()));如果(client.Indices.Exists(shapesIndex).Exists)client.Indices.Delete(shapesIndex);client.Indices.Create(shapesIndex,c => c.Map< Shape>(m => m.AutoMap()));client.Bulk(b => b.IndexMany(new [] {新文件{ID = 1LocalityId = 1,LocationShape = GeoWKTReader.Read("POLYGON((30 20,20 15,20 25,30 20))")},新文件{ID = 2LocalityId = 2},}).IndexMany(new []{新形状{ID = 1几何= GeoWKTReader.Read("POLYGON((20 35,10 30,10 10,30 5,45 20,20 35))")}}).Refresh(Refresh.WaitFor));var shapeId = 1;var searchResponse = client.Search< Shape>(s => s尺寸(0)查询(q => + q.Ids(i => i.Values(shapeId))&&+ q.Exists(e => e.Field("geometry"))));Func< QueryContainerDescriptor< Document>,QueryContainer>geoShapeQuery = q =>q;如果(searchResponse.Total == 1)geoShapeQuery = q =>+ q.GeoShape(g => g.Field("locationShape").Relation(GeoShapeRelation.Inner).IndexedShape(f => f.Id(shapeId).Index(shapesIndex).Path("geometry")));client.Search< Document>(s => s查询(q => + q.Term(t => t.Field(f => f.LocalityId)值(2))||geoShapeQuery(q)));}公共课文件{public int ID {get;放;}public int LocalityId {get;放;}公开IGeoShape LocationShape {get;放;}}公共课形{public int ID {get;放;}公开IGeoShape几何{放;}}
如果将 var shapeId = 1;
更改为 var shapeId = 2;
,则在搜索文档索引时,不会将geoshape查询添加到过滤器子句中./p>
We are using a filter as per following:
filters.Add(fq => fq
.Term(t => t
.Field(f => f.LocalityId)
.Value(locationParams[2])) || fq
.GeoShape(g => g
.Field("locationShape")
.Relation(GeoShapeRelation.Within)
.IndexedShape(f => f
.Id(searchCriteria.spLocationId)
.Index(indexName)
.Path("geometry")
)
)
);
However, if the geometry field is missing, Elasticsearch throws an exception.
Is there anyway to avoid this by using a default (Null Value) in the mapping or any other way.
It is not possible to avoid the exception in this case. Elasticsearch assumes that the parameters that the user provides to a pre-indexed shape are valid.
Ideally, the values supplied to the indexed shape should be constrained in a manner that prevents an end user from supplying invalid values. If that is unfeasible, you could run a bool
query with filter clauses of exists
query and ids
query on the indexName
index before adding the indexed shape geoshape query filter to the search request.
For example
private static void Main()
{
var documentsIndex = "documents";
var shapesIndex = "shapes";
var host = "localhost";
var pool = new SingleNodeConnectionPool(new Uri($"http://{host}:9200"));
var settings = new ConnectionSettings(pool)
.DefaultMappingFor<Document>(m => m.IndexName(documentsIndex))
.DefaultMappingFor<Shape>(m => m.IndexName(shapesIndex));
var client = new ElasticClient(settings);
if (client.Indices.Exists(documentsIndex).Exists)
client.Indices.Delete(documentsIndex);
client.Indices.Create(documentsIndex, c => c
.Map<Document>(m => m
.AutoMap()
)
);
if (client.Indices.Exists(shapesIndex).Exists)
client.Indices.Delete(shapesIndex);
client.Indices.Create(shapesIndex, c => c
.Map<Shape>(m => m
.AutoMap()
)
);
client.Bulk(b => b
.IndexMany(new [] {
new Document
{
Id = 1,
LocalityId = 1,
LocationShape = GeoWKTReader.Read("POLYGON ((30 20, 20 15, 20 25, 30 20))")
},
new Document
{
Id = 2,
LocalityId = 2
},
})
.IndexMany(new []
{
new Shape
{
Id = 1,
Geometry = GeoWKTReader.Read("POLYGON ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35))")
}
})
.Refresh(Refresh.WaitFor)
);
var shapeId = 1;
var searchResponse = client.Search<Shape>(s => s
.Size(0)
.Query(q => +q
.Ids(i => i.Values(shapeId)) && +q
.Exists(e => e.Field("geometry"))
)
);
Func<QueryContainerDescriptor<Document>, QueryContainer> geoShapeQuery = q => q;
if (searchResponse.Total == 1)
geoShapeQuery = q => +q
.GeoShape(g => g
.Field("locationShape")
.Relation(GeoShapeRelation.Within)
.IndexedShape(f => f
.Id(shapeId)
.Index(shapesIndex)
.Path("geometry")
)
);
client.Search<Document>(s => s
.Query(q => +q
.Term(t => t
.Field(f => f.LocalityId)
.Value(2)
) || geoShapeQuery(q)
)
);
}
public class Document
{
public int Id { get; set; }
public int LocalityId { get; set; }
public IGeoShape LocationShape { get; set; }
}
public class Shape
{
public int Id { get; set; }
public IGeoShape Geometry { get; set; }
}
If var shapeId = 1;
is changed to var shapeId = 2;
then the geoshape query is not added to the filter clauses when searching on the documents index.
这篇关于NEST API GeoShapes字段的默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!