【问题标题】:azure cognitive search - geography point problem天蓝色认知搜索 - 地理点问题
【发布时间】:2021-03-11 19:54:56
【问题描述】:

我指定一个字段如下:

    [SimpleField(IsFilterable = true, IsSortable = true)]
    public  Microsoft.Spatial.GeographyPoint Location { get; set; }

在我的索引中,我可以看到它已成功创建并且内容正确,但是当我尝试使用 geo.distance 进行搜索时,它会引发以下错误:

$filter=geo.distance(Location, geography'POINT(-82.51571 31.89063)') le 30

错误:

“无效的表达式:名称为'geo.distance'的函数没有函数签名与指定的参数匹配。考虑的函数签名是:geo.distance(Edm.GeographyPoint Nullable=true, Edm.GeographyPoint Nullable=true); geo.distance(Edm.GeometryPoint Nullable=true, Edm.GeometryPoint Nullable=true)。\r\n参数名称:$filter"

【问题讨论】:

  • 我想我可能知道问题出在哪里,但首先我需要知道——Azure 认知搜索索引中字段的实际类型是什么?是 Edm.GeographyPoint、Edm.ComplexType 还是别的什么?
  • 嗨@BruceJohnston 我已经发送了一封关于这个问题的详细电子邮件。我手动创建了一个字段作为 Edm.GeographyPoint 以支持 geo.distance 功能,但我无法索引内容。似乎这是省略 Type 属性的序列化程序的问题

标签: azure azure-cognitive-search azure-search-.net-sdk


【解决方案1】:

Azure SDK 正在开发全面的空间类型以跨服务共享。目前,需要一个单独的包来支持 Microsoft.Spatial。如果您使用 System.Text.Json(与“Azure.*”匹配的 Azure SDK 包的默认设置),请使用 https://www.nuget.org/packages/Microsoft.Azure.Core.Spatial/1.0.0-beta.1。如果您使用的是 Json.NET(即 Newtonsoft.Json),请使用 https://www.nuget.org/packages/Microsoft.Azure.Core.Spatial.NewtonsoftJson/1.0.0-beta.1

查看https://github.com/Azure/azure-sdk-for-net/blob/Microsoft.Azure.Core.Spatial_1.0.0-beta.1/sdk/core/Microsoft.Azure.Core.Spatial.NewtonsoftJson/README.md 了解如何使用前者的示例,查看https://github.com/Azure/azure-sdk-for-net/blob/Microsoft.Azure.Core.Spatial.NewtonsoftJson_1.0.0-beta.1/sdk/core/Microsoft.Azure.Core.Spatial.NewtonsoftJson/README.md 了解后者。

您需要使用这些来生成您的 SearchIndex 并重新发布,以便空间 OData 过滤器能够正常工作。

对您发送的源进行一些修改(没有资源名称和 API 密钥 - 使用环境变量是个好主意,即使这些资源是临时的),您将使用如下内容:

            Uri serviceEndpoint = new Uri($"https://{serviceName}.search.windows.net/");
            var credential = new AzureKeyCredential(apiKey);

            JsonSerializerOptions serializerOptions = new JsonSerializerOptions
            {
                Converters =
                {
                    new MicrosoftSpatialGeoJsonConverter()
                },
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            };
            SearchClientOptions clientOptions = new SearchClientOptions
            {
                Serializer = new JsonObjectSerializer(serializerOptions)
            };

            var adminClient = new SearchIndexClient(serviceEndpoint, credential, clientOptions);
            var searchClient = new SearchClient(serviceEndpoint, indexName, credential, clientOptions);

            FieldBuilder fieldBuilder = new FieldBuilder
            {
                Serializer = clientOptions.Serializer
            };

            var definition = new SearchIndex(indexName)
            {
                Fields = fieldBuilder.Build(typeof(Sample))
            };

            adminClient.CreateOrUpdateIndex(definition);

            IndexDocumentsBatch<Sample> batch = IndexDocumentsBatch.Create(
                new IndexDocumentsAction<Sample>(IndexActionType.MergeOrUpload, new Sample { Id = "1", Location = GeographyPoint.Create(0, 0) }
            ));

            try
            {
                IndexDocumentsResult result = searchClient.IndexDocuments(batch);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
                // If for some reason any documents are dropped during indexing, you can compensate by delaying and
                // retrying. This simple demo just logs the failed document keys and continues.
                Console.WriteLine("Failed to index some of the documents: {0}");
            }

            Console.WriteLine("Hello World!");

还有你的模型:

    public class Sample
    {
        [SimpleField(IsKey = true, IsFilterable = true, IsSortable = true)]
        public string Id { get; set; }

        [SimpleField(IsFilterable = true, IsSortable = true)]
        public GeographyPoint Location { get; set; }
    }

尽管您最初没有使用 FieldBuilder,但您为字段指定了 camelCase,但使用 PascalCase 声明了这些字段。请注意,Azure 认知搜索区分大小写,包括字段名称。

【讨论】:

  • 感谢 Heath,但问题与将数据推送到 Azure 认知搜索索引有关。请求无效。详细信息:参数:找到没有类型名称的资源,但未指定预期类型。要允许没有类型信息的条目,还必须在指定模型时指定预期类型。
  • 您需要将序列化程序传递给 FieldBuilder 并重新生成索引。似乎我在自述文件中遗漏了这个例子,但可以添加一些东西。实际上,创建 FieldBuilder 的新实例并将其 Serializer 属性设置为您在示例中创建的序列化程序。
  • 我在上面也给出了错误的链接。第二段的第一个链接应该是:github.com/Azure/azure-sdk-for-net/blob/…(我更改了标签但没有更改路径)。对不起。尽管如此,仍然基本相同,我将更新以包括如何将它与 FieldBuilder 一起使用。
  • 我也试过了:FieldBuilder fieldBuilder = new FieldBuilder(); fieldBuilder.Serializer = new JsonObjectSerializer(serializerOptions);我在 DL 中发送了一个示例应用程序。你能看看并检查我遗漏了什么吗? PS:之前我发送邮件后添加的代码
猜你喜欢
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多