【问题标题】:How to clear all data from AWS CloudSearch?如何清除 AWS CloudSearch 中的所有数据?
【发布时间】:2013-07-09 20:11:15
【问题描述】:

我有一个仍在开发中的 AWS CloudSearch 实例。

有时,例如当我对字段的格式进行一些修改时,我发现自己想要清除所有数据并重新生成它。

有什么方法可以使用控制台清除所有数据,还是我必须通过编程方式进行?

如果我必须使用编程方式(即生成并发布一堆“删除”SDF 文件),有什么好的方法可以查询 CloudSearch 实例中的所有文档吗?

我想我可以删除并重新创建实例,但这需要一段时间,并且会丢失所有索引/排名表达式/文本选项/等

【问题讨论】:

  • 创建一个脚本以使用所有参数创建您的搜索域

标签: amazon-web-services amazon-cloudsearch


【解决方案1】:

在命令行中使用awsjq(在mac 上使用bash 测试):

export CS_DOMAIN=https://yoursearchdomain.yourregion.cloudsearch.amazonaws.com

# Get ids of all existing documents, reformat as
# [{ type: "delete", id: "ID" }, ...] using jq
aws cloudsearchdomain search \
  --endpoint-url=$CS_DOMAIN \
  --size=10000 \
  --query-parser=structured \
  --search-query="matchall" \
  | jq '[.hits.hit[] | {type: "delete", id: .id}]' \
  > delete-all.json

# Delete the documents
aws cloudsearchdomain upload-documents \
  --endpoint-url=$CS_DOMAIN \
  --content-type='application/json' \
  --documents=delete-all.json

有关 jq 的更多信息,请参阅Reshaping JSON with jq

2017 年 2 月 22 日更新

添加了 --size 以一次获取最大文档数 (10,000)。您可能需要多次重复此脚本。此外,--search-query 可以采取更具体的方式,如果您想对删除的文档有选择性。

【讨论】:

【解决方案2】:

我能找到的最佳答案在某种程度上隐藏在 AWS 文档中。也就是说:

Amazon CloudSearch 目前不提供删除机制 域中的所有文档。但是,您可以克隆域 配置以从空域重新开始。更多 信息,请参阅Cloning an Existing Domain's Indexing Options

来源:http://docs.aws.amazon.com/cloudsearch/latest/developerguide/Troubleshooting.html#ts.cleardomain

【讨论】:

  • 叹息;希望他们添加一种方法来做到这一点。我确实喜欢点击那些不小心做坏事的按钮!
  • 同意这个功能应该更容易。此外,您的链接似乎不再包含有关克隆域的任何信息……
  • 但是我在awsdocs.s3.amazonaws.com/cloudsearch/2011-02-01/… 找到了信息——不幸的是,这个过程对我来说无限期地挂起,除了已经不理想之外,因为我必须追踪对端点的所有引用才能更新。
  • 它现在似乎完全消失了。所以看来这个答案不再是答案了。
  • 它不见了... =/
【解决方案3】:

在我这边,我使用了这样的本地 nodejs 脚本:

var AWS = require('aws-sdk');

AWS.config.update({
    accessKeyId: '<your AccessKey>', 
    secretAccessKey: '<Your secretAccessKey>',
    region: '<your region>',
    endpoint: '<your CloudSearch endpoint'
});

var params = {
       query:"(or <your facet.FIELD:'<one facet value>' facet.FIELD:'<one facet value>')",
       queryParser:'structured'
};


var cloudsearchdomain = new AWS.CloudSearchDomain(params);
cloudsearchdomain.search(params, function(err, data) {
    var fs = require('fs');
    var result = [];
    if (err) {
        console.log("Failed");
        console.log(err);
    } else {
        resultMessage = data;
        for(var i=0;i<data.hits.hit.length;i++){
            result.push({"type":"delete","id":data.hits.hit[i].id});
        }    

        fs.writeFile("delete.json", JSON.stringify(result), function(err) {
            if(err) {return console.log(err);}
        console.log("The file was saved!");
        });
    }
});

您必须至少知道 on facets 的所有值,才能请求所有 ID。在我的代码中,我只放了 2(在 (或 ....) 部分),但你可以有更多。

完成后,您将拥有一个 delete.json 文件,可通过以下命令与 AWS-CLI 一起使用:

aws cloudsearchdomain upload-documents --documents delete.json --content-type application/json --endpoint-url <your CloudSearch endpoint>

...这对我有用!

【讨论】:

  • 如果您有必填字段(在我的情况下为 application_name),查询会更高效一些。然后,它将是 query:"(not application_name:'')"
  • 谢谢,效果很好。我必须将大小参数添加到搜索中才能获取我的所有文档
【解决方案4】:

我一直在执行以下操作,使用 python 适配器 boto 来清空 cloudsearch。不漂亮,但它完成了工作。困难的部分是平衡您获取的数量是否在 cloudsearch 5mb 限制内。

    count = CloudSearchAdaptor.Instance().get_total_documents()
    while count > 0:
         results = CloudSearchAdaptor.Instance().search("lolzcat|-lolzcat", 'simple', 1000)
         for doc in results.docs:
             CloudSearchAdaptor.Instance().delete(doc['id'])

         CloudSearchAdaptor.Instance().commit()
         #add delay here if cloudsearch takes to long to propigate delete change            
         count = CloudSearchAdaptor.Instance().get_total_documents()

Cloudsearch 适配器类如下所示:

from boto.cloudsearch2.layer2 import Layer2
from singleton import Singleton

@Singleton
class CloudSearchAdaptor:

    def __init__(self):
        layer2 = Layer2(
            aws_access_key_id='AWS_ACCESS_KEY_ID',
            aws_secret_access_key='AWS_SECRET_ACCESS_KEY',
            region='AWS_REGION'
        )
        self.domain = layer2.lookup('AWS_DOMAIN'))
        self.doc_service = self.domain.get_document_service()
        self.search_service = self.domain.get_search_service()

@staticmethod
def delete(id):
    instance = CloudSearchAdaptor.Instance()
    try:
        response = instance.doc_service.delete(id)
    except Exception as e:
        print 'Error deleting to CloudSearch'

@staticmethod
def search(query, parser='structured', size=1000):
    instance = CloudSearchAdaptor.Instance()
    try:
        results = instance.search_service.search(q=query, parser=parser, size=size)
        return results
    except Exception as e:
        print 'Error searching CloudSearch'

@staticmethod
def get_total_documents():
    instance = CloudSearchAdaptor.Instance()
    try:
        results = instance.search_service.search(q='matchall', parser='structured', size=0)
        return results.hits
    except Exception as e:
        print 'Error getting total documents from CloudSearch'

@staticmethod
def commit():
    try:
        response = CloudSearchAdaptor.Instance().doc_service.commit()
        CloudSearchAdaptor.Instance().doc_service.clear_sdf()
    except Exception as e:
        print 'Error committing to CloudSearch'

【讨论】:

    【解决方案5】:

    在 PHP 上,我设法使用 AWS PHP SDK 创建了一个用于清理所有记录的脚本:

    clean.php - http://pastebin.com/Lkyk1D1i config.php - http://pastebin.com/kFkZhxCc

    您需要在 config.php 上配置您的密钥,在 clean.php 上配置您的端点,下载 AWS PHP 开发工具包,一切顺利!!!

    请注意,它最多只能清理 10000 个文档。因为亚马逊有限制。

    【讨论】:

      【解决方案6】:

      您可以手动将文档批次直接上传到 AWS CloudSearch、仪表板 > 上传文档。 如果您可以枚举所有要删除的索引 ID,则可以创建一个脚本来生成文档批处理或手动生成它。

      文档批处理格式应该是这样的

      sample.json

      [
          {
              "type": "delete",
              "id": "1"
          },
          {
              "type": "delete",
              "id": "2"
          }
      ]
      

      如何枚举所有索引 - 运行测试搜索

      • 搜索:id:*(或您确定所有人都可以使用的任何字段)
      • 查询解析器:Lucene

      【讨论】:

        【解决方案7】:

        我已经设法为它创建了一个 PowerShell 脚本。在这里查看我的网站:http://www.mpustelak.com/2017/01/aws-cloudsearch-clear-domain-using-powershell/

        脚本:

        $searchUrl = '[SEARCH_URL]'
        $documentUrl = '[DOCUMENT_URL]'
        $parser = 'Lucene'
        $querySize = 500
        
        function Get-DomainHits()
        {
            (Search-CSDDocuments -ServiceUrl $searchUrl -Query "*:*" -QueryParser $parser -Size $querySize).Hits;
        }
        
        function Get-TotalDocuments()
        {
            (Get-DomainHits).Found
        }
        
        function Delete-Documents()
        {
            (Get-DomainHits).Hit | ForEach-Object -begin { $batch = '[' } -process { $batch += '{"type":"delete","id":' + $_.id + '},'} -end { $batch = $batch.Remove($batch.Length - 1, 1); $batch += ']' }
        
            Try
            {
                Invoke-WebRequest -Uri $documentUrl -Method POST -Body $batch -ContentType 'application/json'
            }
            Catch
            {
                $_.Exception
                $_.Exception.Message
            }
        }
        
        $total = Get-TotalDocuments
        while($total -ne 0)
        {
            Delete-Documents
        
            $total = Get-TotalDocuments
        
            Write-Host 'Documents left:'$total
            # Sleep for 1 second to give CS time to delete documents
            sleep 1
        }
        

        【讨论】:

          【解决方案8】:

          以下Java版本可清除云搜索域内的所有数据:

          private static final AmazonCloudSearchDomain cloudSearch = Region
                  .getRegion(Regions.fromName(CommonConfiguration.REGION_NAME))
                  .createClient(AmazonCloudSearchDomainClient.class, null, null)
                  .withEndpoint(CommonConfiguration.SEARCH_DOMAIN_DOCUMENT_ENDPOINT);
          
          public static void main(String[] args) {
          
              // retrieve all documents from cloud search
              SearchRequest searchRequest = new SearchRequest().withQuery("matchall").withQueryParser(QueryParser.Structured);
              Hits hits = cloudSearch.search(searchRequest).getHits();
          
              if (hits.getFound() != 0) {
                  StringBuffer sb = new StringBuffer();
                  sb.append("[");
          
                  int i = 1;
                  // construct JSON to delete all
                  for (Hit hit : hits.getHit()) {
                      sb.append("{\"type\": \"delete\",  \"id\": \"").append(hit.getId()).append("\"}");
                      if (i < hits.getHit().size()) {
                          sb.append(",");
                      }
                      i++;
                  }
          
                  sb.append("]");
          
                  // send to cloud search
                  InputStream documents = IOUtils.toInputStream(sb.toString());
                  UploadDocumentsRequest uploadDocumentsRequest = new UploadDocumentsRequest()
                          .withContentType("application/json").withDocuments(documents).withContentLength((long) sb.length());
                  cloudSearch.uploadDocuments(uploadDocumentsRequest);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-04-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-05-29
            • 2019-05-13
            相关资源
            最近更新 更多