2015-03-12 13 views
13

Potrzebuję usunąć pole we wszystkich dokumentach indeksowanych do Elasticsearch. Jak mogę to zrobić. Czy którekolwiek z zapytań o usunięcie pomoże mi to osiągnąć.Usuwanie pola z dokumentu Elasticsearch

+0

Domyślnie nie jest to możliwe, ponieważ teraz Lucene nie obsługuje tego tego. Zasadniczo można tylko umieszczać lub usuwać całe dokumenty Lucene z indeksów Lucene .1 Pobierz pierwszą wersję swojego dokumentu. 2 usuń pole 3 Naciśnij tę nową wersję dokumentu. – Backtrack

Odpowiedz

18

Co @backtrack powiedział jest prawdą, ale to nie jest bardzo wygodny sposób robienia tego w Elasticsearch. Elasticsearch usunie wewnętrzną złożoność usuwania. Trzeba użyć aktualizacji API do osiągnięcia tego celu -

curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{ 
    "script" : "ctx._source.remove(\"name_of_field\")" 
}' 

Można znaleźć więcej dokumentacji here.

Uwaga: Zgodnie z elastycznej Szukaj 6 które są wymagane, aby zawierać nagłówek Content-Type:

-H 'Content-Type: application/json' 
+0

Jaka jest wydajność tego dokumentu, jeśli masz miliard dokumentów w tym polu? –

+0

Faktyczny dokument zostanie usunięty, a nowy zostanie dodany do każdej z takich zmian. –

+0

Uwaga dla ElasticSearch 5.0: powinieneś używać nazwanego parametru zamiast nazwy zakodowanej na stałe. Parametry są szybsze i nie przekroczą limitu kompilacji skryptu. Zobacz [dokumentacja] (https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html#prefer-params). –

7

Domyślnie nie jest to możliwe, ponieważ teraz Lucene tego nie obsługuje. Zasadniczo można tylko umieszczać lub usuwać całe dokumenty Lucene z indeksów Lucene.

  1. Pobierz pierwszą wersję swojej doc
  2. usunąć pole
  3. Push nowej wersji swojej doc
11

Elasticsearch dodaną update_by_query w 2.3. Ten eksperymentalny interfejs umożliwia aktualizację wszystkich dokumentów pasujących do zapytania.

Wewnętrznie elastyczne wyszukiwanie polega na skanowaniu/przewijaniu w celu zebrania partii dokumentów, a następnie ich aktualizacji, tak jak w przypadku interfejsu aktualizacji zbiorczej. Jest to szybsze niż robienie tego ręcznie za pomocą własnego interfejsu skanowania/przewijania ze względu na brak obciążenia sieci i serializacji. Każdy rekord musi być załadowany do pamięci RAM, zmodyfikowany, a następnie zapisany.

Wczoraj usunąłem duże pole z mojego klastra ES. Widziałem stałą przepustowość 10.000 rekordów na sekundę podczas update_by_query, ograniczoną przez CPU, a nie IO.

Sprawdź w ustawieniu conflict=proceed, czy klastrze ma inny ruch aktualizacji, lub całe zadanie zostanie zatrzymane, gdy trafi na ConflictError, gdy jeden z rekordów zostanie zaktualizowany pod jedną z partii.

Podobnie ustawienie wait_for_completion=false spowoduje, że update_by_query będzie działał przez interfejs tasks. W przeciwnym razie zadanie zostanie zakończone, jeśli połączenie zostanie zamknięte.

url: ciało

http://localhost:9200/type/_update_by_query?wait_for_completion=false&conflict=proceed 

POST:

{ 
    "script": ctx._source.remove("name_of_field"), 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "exists": { 
      "field": "name_of_field" 
      } 
     } 
     ] 
    } 
    } 
} 

Od Elasticsearch 1.43, inline groovy scripting is disabled by default. Musisz go włączyć, aby skrypt wbudowany działał, dodając script.inline: true do pliku konfiguracyjnego.

Lub prześlij groovy jako skrypt i użyj formatu "script": { "file": "scriptname", "lang": "groovy"}.

+0

To, czego jeszcze nie wiem, to sposób odzyskania pola field_data używanego przez to pole. Mając nadzieję na ponowne uruchomienie, spowoduje to ponowne załadowanie zleceń. – spazm

+1

Ciało wymagało niewielkiej modyfikacji, ale poza tym działa to doskonale. Musiałem zawinąć skrypt w obiekcie JSON, prawdopodobnie dlatego, że interfejs API nieco się zmienił. – Peter

Powiązane problemy