2015-04-06 15 views
6

Tôi có tài liệu elasticsearch theo định dạng sau. Tôi cần phải cập nhật một phần "x" lĩnh vực và thêm một dict python trong nó.cập nhật một phần elasticsearch với python

{ 
     "_index": "gdata34", 
     "_type": "gdat", 
     "_id": "328091-72341-118", 
     "_version": 1, 
     "_score": 1, 
     "_source": { 
      "d": { 
       "Thursday": { 
        "s": "" 
       }, 
       "Email": { 
        "s": "" 
       }, 
       "Country": { 
        "s": "US" 
       }, 

      }, 
      "x": { 
       "Geo": { 
        "s": "45.335428,-118.057133", 
        "g": [ 
         -118.057133 
         , 
         45.335428 
        ] 
       } 
      }, 
      } 
     } 

Tôi đã thử đoạn code sau để cập nhật:

from elasticsearch import Elasticsearch, exceptions 
import pprint 


elasticsearch = Elasticsearch() 
doc = elasticsearch.get(index='gdata34', doc_type='gdat', id='328091-72341-7') 

elasticsearch.update(index='gdata34', doc_type='gdat', id='328091-72341-7', 
        body={"script":"ctx._source.x += y", 
          "params":{"y":"z"} 
        } 
        ) 
elasticsearch.indices.refresh(index='gdata34') 
new_doc = elasticsearch.get(index='gdata34', doc_type='gdat', id='328091-72341-7') 

Tôi nhận được lỗi này:

elasticsearch.exceptions.RequestError: TransportError(400, u'ElasticsearchIllegalArgumentException[failed to execute script]; nested: ScriptException[dynamic scripting for [groovy] disabled]; ') 

đúng cách để làm cập nhật từng phần trong elasticsearch sử dụng python là gì?

+0

Bạn đang sử dụng phiên bản ES nào? –

+0

@LukasGraf 1.4.4 – Anish

Trả lời

9

Để tham khảo trong tương lai, phương pháp cập nhật từng phần sau đây đã hoạt động.

elasticsearch.update(index='gdata34', doc_type='gdat', id='328091-72341-7', 
        body={ 
         'doc': {'x': {'y':'z'}} 
        } 
        ) 
1

Từ ElasticSearch docs on scripting:

We recommend running Elasticsearch behind an application or proxy, which protects Elasticsearch from the outside world. If users are allowed to run dynamic scripts (even in a search request), then they have the same access to your box as the user that Elasticsearch is running as. For this reason dynamic scripting is allowed only for sandboxed languages by default.

Bây giờ, trong phiên bản mới ES đã có một lỗi trong các lỗ hổng trong công cụ scripting Groovy cho phép các kịch bản để thoát khỏi sandbox và thực hiện các lệnh shell là người dùng đang chạy máy ảo Java Elasticsearch - đó là lý do tại sao Groovy sandbox is disabled by default in recent versions và do đó việc thực thi các tập lệnh Groovy được truyền trong phần yêu cầu hoặc từ chỉ mục .scripts. Cách duy nhất để thực thi các kịch bản lệnh Groovy với cấu hình mặc định này là đặt chúng trong thư mục config/scripts/ trên nút.

Vì vậy, bạn có hai lựa chọn:

  • Nếu dụ ES của bạn là không truy cập trực tiếp và được đảm bảo sau một proxy, bạn có thể bật sandboxing Groovy một lần nữa bằng cách thiết lập script.groovy.sandbox.enabled: true trong config/elasticsearch.yml vào nút của bạn (s). Nếu thể hiện ES của bạn có thể truy cập bằng
  • Bạn có thể chuẩn bị tập lệnh và đặt nó trên hệ thống tệp trong thư mục config/scripts của (các) nút của bạn và gọi theo tên. Xem Running Groovy Scripts without Dynamic Scripting để biết chi tiết.
+0

chúng tôi có thể sử dụng những điều sau đây không? Elasticsearch.update (index = 'gdata34', doc_type = 'gdat', id = '328091-72341-7', body = { 'doc': {' x ': {' y ':' z '}} } ) – Anish

+1

Có, nhưng hãy nhớ đọc [tài liệu] (http://www.elastic.co/guide/en/elasticsearch/reference/1.4/ docs-update.html) - trừ khi bạn chỉ định '" detect_noop ": true' điều này sẽ luôn dẫn đến tài liệu đang được cập nhật, ngay cả khi quá trình hợp nhất không phát hiện bất kỳ thay đổi nào. –

+0

Ít nhất với ElasticSearch 2.3 (phiên bản mới nhất tại thời điểm này), 'detect_noop' ​​được bật theo mặc định. –

Các vấn đề liên quan