Problem/Motivation

If you create a translation of an article in Ukrainian, for example, and then delete it, then on page /admin/config/search/pages we see the following: "There is 1 item left to index."

Running the cron does not solve the problem.

Result:
On page /admin/config/search/pages we see the following: "There is 1 item left to index."
If this is repeated for 100 articles, the indexing of the site will stop.

There is such an entry in the database:
SELECT * FROM `d8_search_dataset`

  • sid = 1
  • langcode = uk
  • type = node_search
  • data = "some text"
  • reindex = 1618155506

Steps to reproduce

1. Install Drupal 8.9.13 (Latest version for now)
2. Install modules (from core): Configuration Translation, Content Translation, Interface Translation,
Language
3. /admin/config/regional/language - Add the Ukrainian language, for example
4. /admin/structure/types/manage/article - "Enable translation"
5. create an article and add a translation to it.
6. Runs Cron
7. Delete article translation.
8. Runs Cron

Proposed resolution

In Node::postSave() execture a new private method nodeSearchRemoveDeletedTranslations that will remove deleted translations from the search index.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Problem/Motivation

Issue fork drupal-3208247

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

orb created an issue. See original summary.

cilefen’s picture

Does this item remain forever despite cron executions?

orb’s picture

Running the cron does not remove this item. Over time, there will be more and more of these items.

cilefen’s picture

This may be related to, or currently part of, this effort #2723323: [META] Clean up references to deleted entities.

orb’s picture

I don't know, but the Search module should remove the index.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Version: 9.5.x-dev » 11.x-dev
Issue summary: View changes
Issue tags: +Bug Smash Initiative

I tested on Drupal 11.x and, using the steps in the Issue Summary, I can confirm the problem still exists.

zniki.ru made their first commit to this issue’s fork.

nikolay shapovalov’s picture

Status: Active » Needs work

Provided tests to display described issue.
I created draft MR.

sukr_s made their first commit to this issue’s fork.

sukr_s’s picture

Issue summary: View changes
Status: Needs work » Needs review

unable to change the draft status on the MR

sukr_s changed the visibility of the branch 3208247-after-deleting-a to hidden.

sukr_s’s picture

unable to change the draft status in MR so reverted the changes and created a new mr.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs subsystem maintainer review

Not sure a hook is the best place for this. There's NodeSearch.php shouldn't that leveraged to handle a deletion. Or does content_translation need a search plugin as well?

smustgrave’s picture

sukr_s’s picture

Status: Needs work » Needs review

When a node is deleted, it's removed from the search index in the node::preDelete event. It's not handled by NodeSearch or content_moderation. On the same lines when a translation is deleted, it must be removed from the search index using the translation_delete hook.

smustgrave’s picture

Status: Needs review » Needs work

Still think there could be a better way to go about it. But at a minimum believe the change and test should belong in the search module. Not all sites use the search module and even though this hook wouldn’t do anything it will still get called every translation deletion.

sukr_s’s picture

Status: Needs work » Needs review

w.r.t to alternate approach to solve this, it would be far more expensive to find what was deleted in a cron run e.g. run though list of languages configured for the site, then the list of languages currently available to for the node and then to clear the index for missing languages. So I believe it's best done at the time of deletion.

I also think that this should be in search module. However this would result in hard coding the type node_search (used in clear method) in search module which would not be right since search module does not own the 'node_search' plugin. I could not find a method to dynamically determine the search plugin type based on entity type. Therefore chose to place it in the node module.

is it possible to find search plugin type based on entity type or is it ok to hard code the type in search module?

smustgrave’s picture

Will see if the sub maintainer takes a look in a few weeks.

pwolanin’s picture

Node module is also responding to various changes in hooks (e.g. comment update) and calling node_reindex_node_search()

This feels like a similar case, so I think the approach in the MR is reasonable given the limitations of the system.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs subsystem maintainer review

Thanks @pwolanin for taking a look!

https://git.drupalcode.org/issue/drupal-3208247/-/jobs/1453892 shows the test coverage

Applied 1 more nitpicky change but this got sign off from the sub-maintainer so seems fine solution that addresses the problem.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Seems tests are failing.

smustgrave changed the visibility of the branch 11.x to hidden.

smustgrave’s picture

Status: Needs work » Reviewed & tested by the community

I have 0 idea how the suggestion of :void broke so many tests. But started a new MR as the branch name 11.x wasn't good for local (since that's the main branch). Applied the suggestion by @alexpott and tests are green again.

Still very weird.

smustgrave’s picture

Sorry @sukr_s @alexpott for all the noise

alexpott’s picture

Issue tags: +Needs followup

I think we should open a follow-up to add a post update to clean up the incorrect data. This issue stops the rot but the bogus data hangs about.

catch’s picture

Status: Reviewed & tested by the community » Needs work

One question on the MR.

catch’s picture

Actually two questions.

Nodes are marked for reindex in Node::postSave()

   // Reindex the node when it is updated. The node is automatically indexed
    // when it is added, simply by being added to the node table.
    if ($update) {
      node_reindex_node_search($this->id());
    }

If we could detect that a translation is being deleted there (can we?) then we would not need to mark the node for indexing, and then delete it again in the hook implementation added here.

Or... is there somewhere else that has this information instead?

sukr_s’s picture

Status: Needs work » Reviewed & tested by the community

changed to postsave and invoking node_reindex_node_search($this->id()); only if the translation was not deleted.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Left a comment on the MR. I think we need to always mark for reindex. The reindexing is not language specific but doing this is not going to recreate any row.

sukr_s’s picture

Status: Needs work » Reviewed & tested by the community

  • catch committed 7d50211a on 10.3.x
    Issue #3208247 by sukr_s, smustgrave, alexpott, Nikolay Shapovalov, orb...

  • catch committed 179e7370 on 10.4.x
    Issue #3208247 by sukr_s, smustgrave, alexpott, Nikolay Shapovalov, orb...

  • catch committed f90e6a2a on 11.0.x
    Issue #3208247 by sukr_s, smustgrave, alexpott, Nikolay Shapovalov, orb...

  • catch committed 249039ad on 11.x
    Issue #3208247 by sukr_s, smustgrave, alexpott, Nikolay Shapovalov, orb...
catch’s picture

Version: 11.x-dev » 10.3.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 11.x and cherry-picked back through to 10.3.x, thanks!

  • catch committed 48c9bf36 on 10.3.x
    Revert "Issue #3208247 by sukr_s, smustgrave, alexpott, Nikolay...

  • catch committed 5ab56052 on 10.4.x
    Revert "Issue #3208247 by sukr_s, smustgrave, alexpott, Nikolay...

  • catch committed b696c550 on 11.0.x
    Revert "Issue #3208247 by sukr_s, smustgrave, alexpott, Nikolay...

  • catch committed 6980ddf0 on 11.x
    Revert "Issue #3208247 by sukr_s, smustgrave, alexpott, Nikolay...
catch’s picture

Status: Fixed » Needs work

I missed a test failure in the last pipeline here, which then broke HEAD, reverted from all four branches.

sukr_s’s picture

Status: Needs work » Needs review

"commit db83ea46 - Better names and no need to pass translations around" broke the fix, which has now been resolved by reverting the relevant changes.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Edit.

Tests appear green again.

quietone’s picture

Version: 10.3.x-dev » 11.0.x-dev
Issue summary: View changes
Issue tags: +Needs followup

I read the issue summary, comments and the MR. The found two things that need attention

1) The proposed resolution is not what is implemented in the MR.

2) This needs a follow up for https://git.drupalcode.org/project/drupal/-/merge_requests/7966#note_310136

alexpott’s picture

Issue tags: -Needs followup

@quietone the approach changed after that comment and is no longer relevant.

alexpott’s picture

I've moved the private function to be inline - keeping old translation objects around after \Drupal\Core\Entity\ContentEntityBase::postSave feels wrong.

larowlan’s picture

Status: Reviewed & tested by the community » Needs review

Left a comment on the MR - is there really no way to do this from search module or similar, putting it in a specific entity class feels wrong - what about other translatable nodes?

catch’s picture

@larowlan all the search integration for nodes is in node module, like the NodeSearch plugin. I agree it would be much nicer if search module had entity support which was then enabled for nodes by default, but for now this should stay with the rest of the integration.

alexpott’s picture

Status: Needs review » Reviewed & tested by the community

I think catch's answer in #57 menas this can go back to rtbc.

quietone’s picture

I tested this on 11.x today and found that this does remove the deleted item from the search index, but only after a cron run. It still adds it to the search index, so that the search page shows 98% of the site has been indexed. There is 1 item left to index. after the deletion. That is incorrect. And not what I expected from reading the issue title and summary. I expected search to not want to re-index it.

There are the steps I used with the diff applied.

  1. admin/config/search/pages - 100% of the site has been indexed. There are 0 items left to index.
  2. Create article
  3. admin/config/search/pages - 98% of the site has been indexed. There is 1 item left to index.
  4. Run cron
  5. admin/config/search/pages - 100% of the site has been indexed. There are 0 items left to index.
  6. Add translation
  7. admin/config/search/pages - 98% of the site has been indexed. There is 1 item left to index.
  8. Run cron
  9. admin/config/search/pages - 100% of the site has been indexed. There are 0 items left to index.
  10. Delete translation
  11. admin/config/search/pages - 98% of the site has been indexed. There is 1 item left to index.
  12. Run cron
  13. admin/config/search/pages - 100% of the site has been indexed. There are 0 items left to index.

If my testing is confirmed correct then it looks like a follow up is needed for correcting the information on /admin/config/search/pages. Or have I misunderstood something again on this issue?

sukr_s’s picture

When any translation is removed, the original content is also added for index. This behaviour has not changed. Pervious to this fix, after the cron run the original article would get reindexed but the removed translation would be left hanging and still gets reported as "1 item requires indexing".
After this fix, the translation is removed from the index therefore before the cron run it shows 1 item which is the original article and after the cron run, it's zero items.

  • catch committed 9db42462 on 10.4.x
    Issue #3208247 by sukr_s, smustgrave, alexpott, Nikolay Shapovalov,...

  • catch committed 9ed95566 on 11.x
    Issue #3208247 by sukr_s, smustgrave, alexpott, Nikolay Shapovalov,...
catch’s picture

Version: 11.0.x-dev » 10.4.x-dev
Status: Reviewed & tested by the community » Fixed

#60 makes sense to me, the entity will be re-indexed but the translation won't.

Since this caused a regression before, committed to 11.1.x and cherry-picked to 10.4.x, thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.