NEST API GeoShapes字段的默认值

问题描述 投票:0回答:1

我们正在使用以下过滤器:

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")
        )
    )
);

但是,如果geometry字段丢失,Elasticsearch会引发异常。

无论如何,可以通过在映射中使用默认值(空值)或任何其他方式来避免这种情况。

elasticsearch nest
1个回答
0
投票

在这种情况下,无法避免例外。 Elasticsearch假定用户提供给预索引形状的参数有效。

理想情况下,应以防止最终用户提供无效值的方式约束提供给索引形状的值。如果这不可行,则可以在将索引的形状几何形状查询过滤器添加到搜索请求之前,对bool索引运行带有exists查询和ids查询的过滤子句的indexName查询。

例如

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; }
}

如果将var shapeId = 1;更改为var shapeId = 2;,则在文档索引上搜索时,几何形状查询不会添加到过滤器子句中。

© www.soinside.com 2019 - 2024. All rights reserved.