Azure搜索返回已删除的blob资源的结果

时间:2018-02-05 16:27:36

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

我有一个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

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

3 个答案:

答案 0 :(得分:4)

经过一些阅读后,我发现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是安全的。

答案 1 :(得分:3)

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

您可以使用POST对详细on this page的API进行索引,直接删除文档,使用&#34;键&#34;领域。以下示例:

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"
    }
  ]  
} 

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

答案 2 :(得分:1)

这是我实施的一种解决方案,用于消除天蓝色搜索数据源中的斑点。

  • 第1步:从Blob存储中删除文档
  • 第二步:从天蓝色搜索中删除文档

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

  

这是代码示例

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