34

まだ開発中の AWS CloudSearch インスタンスがあります。

フィールドのフォーマットを変更するときなどに、すべてのデータを消去して再生成したくなることがあります。

コンソールを使用してすべてのデータを消去する方法はありますか、それともプログラムによる方法で行う必要がありますか?

プログラムによる手段 (つまり、大量の「削除」SDF ファイルを生成して POST する) を使用する必要がある場合、CloudSearch インスタンス内のすべてのドキュメントに対してクエリを実行する良い方法はありますか?

インスタンスを削除して再作成することもできると思いますが、それには時間がかかり、すべてのインデックス/ランク式/テキスト オプション/その他が失われます

4

8 に答える 8

29

コマンドラインから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 の詳細については、jq を使用した JSON の再形成を参照してください。

2017 年 2 月 22 日更新

--size一度に最大数のドキュメント (10,000) を取得するために追加されました。このスクリプトを複数回繰り返す必要がある場合があります。また、--search-query削除されるドキュメントを選択したい場合は、より具体的なものを取ることができます。

于 2016-10-24T17:32:19.893 に答える
5

私の側では、次のようなローカル 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!");
        });
    }
});

すべての ID を要求できるようにするには、少なくとも on ファセットのすべての値を知っている必要があります。私のコードでは、((または ....)セクション内に) 2 を入れただけですが、それ以上にすることもできます。

完了すると、次のコマンドを使用して AWS-CLI で使用する1 つのdelete.jsonファイルが作成されます。

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

...それは私のために仕事をしました!

于 2015-08-05T13:08:13.077 に答える
3

クラウドサーチを空にするために、Pythonアダプターbotoを使用して、次のことを行ってきました。きれいではありませんが、それは仕事を成し遂げます。難しいのは、取得する量をクラウドサーチの 5 MB の制限内に収めることです。

    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'
于 2014-12-11T23:42:59.240 に答える
2

PHP では、AWS PHP SDK を使用してすべてのレコードをクリーニングするためのスクリプトを作成できました。

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

config.php でキーを設定し、clean.php でエンドポイントを設定し、AWS PHP SDK をダウンロードする必要があります。

最大 10000 ドキュメントのみを消去することに注意してください。Amazonには制限があります。

于 2015-06-01T10:17:23.483 に答える
0

以下の 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);
    }
}
于 2016-06-30T08:19:02.520 に答える