Jak usunąć wszystkie węzły danego typu treści?

31

Mam kilka tysięcy węzłów określonego typu treści. Korzystając z interfejsu internetowego (example.com/admin/content), mogę usunąć tylko około 50 naraz. Jak mogę je szybko usunąć?

Greg
źródło

Odpowiedzi:

32

Jest na to moduł (TM).

Zobacz Usuwanie zbiorcze .

Spowoduje to użycie interfejsu API usługi Batch do usunięcia węzłów, aby uniknąć problemów z przekroczeniem limitu czasu lub pamięci podczas usuwania tysięcy węzłów za pomocą jednego wywołania metody node_delete_multiple ().

Usuwanie zbiorcze to opuszczony moduł. Zobacz alternatywy:

Berdir
źródło
Wow, całkowicie tęskniłem za tym. Dobre znalezisko.
Greg,
4
Inną metodą, która może być użyteczna, jeśli robisz coś więcej niż prosty filtr typu zawartości, jest użycie operacji widoku
geerlingguy
Moduł usuwania zbiorczego jest teraz porzucony. Sugeruje się tam użycie operacji widoku zbiorczego.
Refineo,
26

Patrząc na moduł Devel Generate w poszukiwaniu inspiracji, oto jego funkcja „zabijania zawartości” devel_generate_content_kill:

function devel_generate_content_kill($values) {
  $results = db_select('node', 'n')
              ->fields('n', array('nid'))
              ->condition('type', $values['node_types'], 'IN')
              ->execute();
  foreach ($results as $result) {
    $nids[] = $result->nid;
  }

  if (!empty($nids)) {
    node_delete_multiple($nids);
    drupal_set_message(t('Deleted %count nodes.', array('%count' => count($nids))));
  }
}

Więc spróbowałbym albo użyć Devel Generate, aby usunąć wszystkie węzły, ale nie utworzyć nowych, lub użyć example.com/devel/php, aby zadzwonić devel_generate_content_kill(array('node_types' => array('my_node_type')));bezpośrednio.

tim.plunkett
źródło
17

W Drupal 8 jednym ze sposobów jest użycie metody entityQuery () z metodą EntityStorageInterface :: delete () :

$result = \Drupal::entityQuery("node")
    ->condition("type", "YOUR_CONTENT_TYPE_NAME")
    // If the update is being executed via drush entityQuery will only
    // return the content uid 0 have access to. To return all set
    // accessCheck to false since it defaults to TRUE. 
    ->accessCheck(FALSE)
    ->execute();

$storage_handler = \Drupal::entityTypeManager()->getStorage("node");
$entities = $storage_handler->loadMultiple($result);
$storage_handler->delete($entities);

Jeśli chcesz zastosować inne filtry / warunki, możesz sprawdzić stronę interfejsu QueryInterface

EDYCJA (w inny sposób, dzięki @ 4k4 ):

$storage_handler = \Drupal::entityTypeManager()->getStorage("node");
$entities = $storage_handler->loadByProperties(["type" => "YOUR_CONTENT_TYPE_NAME"]);
$storage_handler->delete($entities);

Jeśli chcesz przetestować kod, możesz użyć:

drush php-eval '$storage_handler = \Drupal::entityTypeManager()->getStorage("node"); $entities = $storage_handler->loadByProperties(["type" => "article"]); $storage_handler->delete($entities);'

Spowoduje to usunięcie wszystkich artykułów.

Adrian Cid Almaguer
źródło
To nie jest poprawne, delete () oczekuje załadowanych encji, a nie identyfikatorów, co zwraca zapytanie encji. Zamiast nieopisowego wyniku $ użyj $ ids lub $ nids, a następnie $ storage-> delete ($ storage-> load ($ ids)).
Berdir
@Berdir dzięki, przetestuję kod jeszcze raz, może ten problem został wprowadzony w jednej edycji
Adrian Cid Almaguer
@Berdir Aktualizuję odpowiedź i testuję kod i działa, problem został wprowadzony w jednej edycji.
Adrian Cid Almaguer,
2
@AdrianCidAlmaguer, możesz zamienić zapytanie na$entities = $storage_handler->loadByProperties(['type' => 'YOUR_CONTENT_TYPE_NAME']);
4k4
1
Ostatnio użyłem tego w haku aktualizacji, warto zauważyć, że jeśli go użyjesz entityQuery , powinieneś ustawić accessCheckna wyciągu. W przeciwnym razie, jeśli uruchomisz go w trybie Drush, domyślnie accessCheck jest ustawiony na true, a wszystkie węzły, do których UID 0 nie ma dostępu, nie zostaną zwrócone.
awm
13

Jeśli chcesz to zrobić wyłącznie za pomocą interfejsu użytkownika, możesz użyć modułu devel_generate.

  1. Przejdź do menu „Generuj zawartość” w „Konfiguracji” (admin / config / development / gener / content).
  2. Wybierz typy zawartości, które chcesz usunąć.
  3. Upewnij się, że pole wyboru obok opcji „Usuń całą zawartość tych typów treści przed wygenerowaniem nowej zawartości” jest zaznaczone.
  4. Ustaw liczbę węzłów, które chcesz wygenerować, na „0”.

W ten sposób nie zostaną wygenerowane żadne węzły, a wszystkie węzły wybranych typów zostaną usunięte.

areynolds
źródło
10

Utwórz plik z poniższym kodem w katalogu głównym instalacji drupal i uruchom plik.

<?php
  require_once './includes/bootstrap.inc';
  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

  $aquery= db_query("SELECT nid FROM {node} AS n WHERE n.type = 'company'");
  while ($row = db_fetch_object($aquery)) {
    node_delete($row->nid);
  }
?>
Satya
źródło
1
Obiekt db_fetch_object nie jest częścią interfejsu API bazy danych D7.
ya.teck
10

Możesz to zrobić w Drupal 7 za pomocą części Wykonaj kod PHP modułu Devel, wprowadzając:

$result= db_query("SELECT nid FROM {node} AS n WHERE n.type = 'TYPE'");
foreach ($result as $record) {
  node_delete($record->nid);
}
Colin Shipton
źródło
1
Wykona się to bardzo powoli, jeśli musisz usunąć tysiące węzłów, lepiej użyć metody, która korzysta z interfejsu API wsadowego, takiego jak VBO.
abielefeldt
6

Zrób to w terminalu, jeśli używasz Drush i usuń wszystkie moduły:

 drush delete-all [content-type-machine-name]


Examples:
 drush delete-all article             Delect all article nodes.
 drush delete-all all                 Delete nodes of all types.
 drush delete-all --reset             Delete nodes of all types, and reset node, revision and comment counters.
 drush delete-all users               Delete users.

Options:
 --reset                              Reset counter for node, revision and comment tables.
 --roles                              pick roles
krzyczeć
źródło
5

Widoki Operacje masowe udostępniają konfigurowalny ekran administratora węzła z funkcją BatchAPI, który umożliwia filtrowanie według typu, wybór wszystkich węzłów pasujących do kryteriów wyszukiwania itp.

To moje praktyczne rozwiązanie w Drupal 6 - oprócz usuwania wsadowego możesz edytować zbiorczo węzły i robić wiele innych rzeczy.

Wygląda na to, że wersja Drupal 7 nie jest jeszcze gotowa - ale oglądałbym ten moduł dla wydania D7.

Darren Petersen
źródło
4

Kolejny fragment to:

$query = db_query("SELECT n.nid FROM {node} n WHERE n.type = 'TO_BE_DELETED'"); 
while ($n = db_fetch_object($query)) 
{
     node_delete($n->nid); 
} 

gdzie TO_BE_DELETEDjest typ zawartości do usunięcia.

Tangurena
źródło
3
Należy zauważyć, że działa tylko dla Drupala 4.6, 5 i 6. Wersja Drupal 7 todb_delete('node')
Greg
4

Z modułem Devel, używając drush:

drush genc 0 --types=article --kill

Lub w interfejsie użytkownika, jak wyjaśniono tutaj: http://befused.com/drupal/delete-nodes-devel

sunzu
źródło
To podmoduł Devel devel_generate, który należy włączyć. A dla wielu typów todrush genc 0 --kill --types="article, page"
leymannx
3

Używam Usuń cały moduł, działa dobrze z D8 i zapewnia bardzo przydatne polecenia drush. Na przykład, aby usunąć całą articlezawartość typu zawartości:

drush delete-all article  
gerzenstl
źródło
Czy to działa z D8? Włączyłem moduł, ale otrzymuję polecenie drush „usuń cały artykuł”. Wyczyściłem również pamięć podręczną drushów
Yassin Tahtah
1

Możesz spróbować usunąć wszystko moduły, przejść do „admin / content / delete_content”, a pojawi się formularz usuwania treści należących do niektórych typów treści.

pozdrowienia

OV
źródło
0

Ten moduł służy do usuwania całej zawartości i / lub użytkowników z witryny. Jest to głównie narzędzie programistyczne, które może się przydać w kilku przypadkach

https://www.drupal.org/project/delete_all

podobnie jak moduł Usuwanie zbiorcze usunie wszystkie węzły określonego typu węzła za pomocą interfejsu API wsadowego. Zaleca się używanie modułu Views Batch Operations (VBO) dla niewielkiej liczby węzłów. Ale jeśli musisz usunąć 10.000 węzłów, ten moduł może być lepszą opcją.

https://www.drupal.org/project/bulkdelete

onlink
źródło
0

Programowo usuń wszystkie węzły typu zawartości tutaj jest funkcja pomocnika:


function _delete_all_nodes_of_type($type = '') {
  // Return all nids of nodes of type.
  $nids = db_select('node', 'n')
    ->fields('n', array('nid'))
    ->condition('n.type', $type)
    ->execute()
    ->fetchCol(); // returns an indexed array
  if (!empty($nids)) {
    node_delete_multiple($nids);
    drupal_set_message(format_plural(count($nids), count($nids) . ' node Deleted.', count($nids) . ' nodes Deleted.'));
  }
}

berramou
źródło
-1

Skończyło się na użyciu db_delete , nie wymaga modułów:

<?php
  db_delete('node')
    ->condition('type', 'MY_CONTENT_TYPE')
    ->execute();
?>

Edytuj / Ostrzeżenie: Zobacz komentarz Berdira poniżej. Ta metoda nie usuwa wszystkich danych związanych z węzłami.

Greg
źródło
3
Problem z tym podejściem polega na tym, że inne moduły również nie są w stanie zareagować i usunąć swoich informacji. W zależności od typu zawartości w tabeli typ_właściwości tego węzła znajdują się informacje specyficzne dla węzła, pola, taksonomie (w rzeczywistości również pole), komentarze i tak dalej. Być może w Twojej bazie danych znajdziesz wiele nieaktualnych informacji.
Berdir,
@Berdir - Ciekawe. Czy istnieje lepszy wbudowany sposób usuwania węzłów?
Greg,
3
Istnieje node_delete () i node_delete_multiple (), patrz odpowiedź tim.plunket, ale to nie jest zaprojektowane do obsługi tysięcy węzłów, patrz api.drupal.org/api/drupal/modules--node--node.module/function / ... . Ładuje wszystkie węzły, a następnie iteruje je w jednym żądaniu. Więc jeśli chcesz usunąć setki lub tysiące węzłów, musisz użyć modułu contrib, takiego jak bulkdelete.
Berdir,
-1

Jeśli nie chcesz kodować, możesz wypróbować ten moduł, https://drupal.org/project/total_control

Przejdź do Pulpitu nawigacyjnego -> Treść, zaznacz całą zawartość (możesz filtrować według typu zawartości), a następnie wybierz „Usuń element”

użytkownik9869932
źródło