【问题标题】:Azure Search returning results for deleted blob resourcesAzure 搜索返回已删除 Blob 资源的结果
【发布时间】:2018-07-15 13:46:13
【问题描述】:

我有一个 Azure 搜索服务,用于根据 BLOB 元数据搜索 BLOBS(即图像)。

搜索所基于的索引设置为每小时刷新一次。

但是,我仍然收到搜索结果中返回的不再存在的 BLOB 的结果。

使用Get Indexer Status API(下面的输出)表明在删除 BLOBS 后索引已成功刷新。

"status": "running",
"lastResult": {
    "status": "success",
    "errorMessage": null,
    "startTime": "2018-02-05T16:00:03.29Z",
    "endTime": "2018-02-05T16:00:03.416Z",
    "errors": [],
    "warnings": [],
    "itemsProcessed": 0,
    "itemsFailed": 0,
    "initialTrackingState": "{\r\n  \"lastFullEnumerationStartTime\": \"2018-02-05T14:59:31.966Z\",\r\n  \"lastAttemptedEnumerationStartTime\": \"2018-02-05T14:59:31.966Z\",\r\n  \"nameHighWaterMark\": null\r\n}",
    "finalTrackingState": "{\"LastFullEnumerationStartTime\":\"2018-02-05T15:59:33.2900956+00:00\",\"LastAttemptedEnumerationStartTime\":\"2018-02-05T15:59:33.2900956+00:00\",\"NameHighWaterMark\":null}"
},
"

如果相关,则使用 Azure Storage Explorer 删除 BLOB

这导致的问题是这些图像正在输出到网页,并且当前显示为丢失的图像,并且使索引大于它需要的大小。

【问题讨论】:

    标签: azure azure-blob-storage azure-cognitive-search


    【解决方案1】:

    虽然软删除是一个选项,但如果您愿意,也可以直接修改索引器所针对的索引。

    您可以使用 POST 索引 API 详细 on this page 直接删除文档,使用它们的“key”字段。下面是一个例子:

    POST https://[service name].search.windows.net/indexes/[index name]/docs/index?api-version=[api-version]   
    Content-Type: application/json   
    api-key: [admin key]  
    {  
      "value": [  
        {  
          "@search.action": "delete",  
          "key_field_name": "value"
        }
      ]  
    } 
    

    假设您没有使用字段映射来修改 blob 索引器的默认“键”行为,从文档 on this page 中,键字段将是 base64 编码 值metadata_storage_path 属性(同样,有关详细信息,请参阅上一个链接)。因此,在删除 blob 时,您可以编写一个触发器,将适当的负载 POST 到您希望从中删除文档的搜索索引。

    【讨论】:

    • 感谢您的替代选项,我会研究哪个更适合我们。
    • 谢谢!我试图找出一种在不重新运行索引的情况下删除的方法,这解决了我的问题。 :-)
    【解决方案2】:

    经过一番阅读,我发现Azure搜索目前唯一支持的删除策略是软删除

    要为 BLOB 存储启用此功能,您必须在每个 BLOB 上创建一个元数据值(例如 IsDeleted)并更新此值以使其能够被删除策略捕获。

    PUT https://[service name].search.windows.net/datasources/blob-datasource?api-version=2016-09-01
    Content-Type: application/json
    api-key: [admin key]
    
    {
    "name" : "blob-datasource",
    "type" : "azureblob",
    "credentials" : { "connectionString" : "<your storage connection string>" },
    "container" : { "name" : "my-container", "query" : "my-folder" },
    "dataDeletionDetectionPolicy" : {
        "@odata.type" :"#Microsoft.Azure.Search.SoftDeleteColumnDeletionDetectionPolicy",     
        "softDeleteColumnName" : "IsDeleted",
        "softDeleteMarkerValue" : "true"
        }
    } 
    

    Full details here

    我需要做一些测试以确保更新元数据是安全的,然后立即删除 BLOB。

    【讨论】:

      【解决方案3】:

      这是我为删除 azure 搜索数据源中的 blob 而实施的解决方案。

      • 第 1 步:从 Blob 存储中删除文档
      • 第 2 步:从 azure 搜索中删除文档

      在字典中键是容器名称,值是文件列表。

      这里是代码示例

       public async Task<bool> RemoveFilesAsync(Dictionary<string, List<string>> listOfFiles)
          {
              try
              {
                  CloudBlobClient cloudBlobClient = searchConfig.CloudBlobClient;
                  foreach (var container in listOfFiles)
                  {
                      List<string> fileIds = new List<string>();
                      CloudBlobContainer staggingBlobContainer = cloudBlobClient.GetContainerReference(container.Key);
      
                      foreach (var file in container.Value)
                      {
                          CloudBlockBlob staggingBlob = staggingBlobContainer.GetBlockBlobReference(file);
      
                          var parameters = new SearchParameters()
                          {
                              Select = new[] { "id", "fileName" }
                          };
      
                          var results = searchConfig.IndexClient.Documents.Search<Document>(file, parameters);
      
                          var filedetails = results.Results.FirstOrDefault(p => p?.Document["fileName"]?.ToString()?.ToLower() == file.ToLower());
                          if (filedetails != null)
                              fileIds.Add(filedetails.Document["id"]?.ToString());
      
                           await staggingBlob.DeleteAsync();
                      }
      
                      // delete from search index
                      var batch = IndexBatch.Delete("id", fileIds);
                      await searchConfig.IndexClient.Documents.IndexWithHttpMessagesAsync(batch);
                  }
      
                  return true;
              }
              catch (Exception ex)
              {
                  throw;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2019-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-11
        • 2019-01-22
        • 1970-01-01
        相关资源
        最近更新 更多