-
-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scout does not update the index for entry set to status disabled, does not delete on entry delete #155
Comments
Possibly, but it also sounds like something we should account for out of the box. PRs are welcome, but I'll try and look at it this week with other updates. |
I have a similar issue, but also with I do this to go through each site and create the indices foreach (Craft::$app->getSites()->getAllSites() as $site) {
$productIndices[] =
\rias\scout\ScoutIndex::create(getenv('ENVIRONMENT').'_products_'.$site->language)
->elementType(\craft\commerce\elements\Product::class)
->criteria(function (\craft\commerce\elements\db\ProductQuery $query) use ($site) {
return $query->siteId($site->id);
})
->transformer(function (\craft\commerce\elements\Product $product) {
return (new \modules\myshopmodule\services\MyshopModuleService)->transformProductData($product);
});
}
return $productIndices;
} this way when I disable a product - it is not removed or only removed from one index. Also it only changes the status for only the index where I disabled the product. What I am trying to achieve is this: Is this doable? |
The way I'm getting around this is I query for all entries regardless of their status and then filter them out on the front end with forced facets |
(Nvm, this works for disabled but not delete) |
@timkelty Hi, hope you are well. I am wondering if you can suggest a workaround for this issue in the meantime.
|
@twosixcode going to take a look at this this afternoon. Stay tuned |
@twosixcode can you try using this branch in your composer.json?
I don't think it is going to solve your delete issue, but it may at least reindex your items with the updated status when you disable. |
@timkelty I just tested A similar issue I encountered is that re-saving of an Expired entry (or setting an entry to Expired) does not cause the entry to be dropped from the Algolia index. I assume this is a similar issue and is related to me using the custom objectId. Any chance that could be addressed in this branch? Are there any plans for deletion to work in this scenario? If not, I'll need to go ahead and pursue a workaround (do you have a suggestion -- ie, a Scout event hook I should use where I can override the objectId to match my situation during delete?) or just move to having a separate index per site. Thanks for your help! I appreciate it. |
@twosixcode can you post your whole scout.php file? or at least the full index we're talking about? |
@twosixcode try something like this as a temporary workaround:
I know you're not actually trying to split elements, but it may trick Scout into deleting things by the distinctID instead. |
Thanks, I tried adding Here are the relevant bits from my scout.php file
And in the transformer module, the relevant bit is what you have already noted, but here is a snippet from the transformer
I am deliberately indexing disabled and expired entries to workaround the issue that cropped up with Scout not dropping records on entry save of disabled and expired entries when my objectId is not the same as the craft entry id (the impetus for creating this issue). I'm now filtering those out on the front end of the site with algolia instantsearch. So really the only outstanding challenge I have to work around is deletion of entries on the craft side not deleting in algolia. |
I don't see
I realize this, but when scout deletes things, if you happen to be using
I think you realize this, but with |
I did, yes. Sorry, I pasted in my current config file. But I did try your suggestion, verbatim. Maybe I need to try it again. It sounds like you expect that to work.
Yes, definitely. I only recently added that, as a workaround. Totally understand what you're saying there. But even without that in there Scout does not drop an expired entry from the index. All told, it's really not a problem for us since we can easily just index disabled and expired entries and then filter them out on the front end with Instantsearch. But I'd love to find a solution for Deletion. Thanks for the continued help! |
Yeah try deleting, with At any rate, it would just be a hack – working on fixing this ASAP. |
@twosixcode otherwise, adding something like this should serve as a workaround for the deletion bit: Event::on(
\craft\services\Elements::class,
\craft\services\Elements::EVENT_AFTER_DELETE_ELEMENT,
function (\craft\events\ElementEvent $event) {
$element = $event->element;
$index = Craft::$container->get(\Algolia\AlgoliaSearch\SearchClient::class)->initIndex('yourIndexName');
$objectIDs = [
$element->id . '-' . 'en',
$element->id . '-' . 'de',
$element->id . '-' . 'etc',
];
$index->deleteObjects($objectIDs);
}
); |
@timkelty Just confirming that we used something similar to the workaround you posted above to ensure deletion. Thanks! |
I was thinking of submitting a PR that replaces this bit: ... with |
@weotch that seems like it would be problematic for large indexes, where batching is required due to the request size limits. |
What if replaceAllObjects() is conditionally used based on the presence of some config option (like
|
I have a site using Craft version 4.3.3 and Scout plugin version 3.0.0 and changing the status of entries from enabled to disabled seems to work for me as long as splitElementsOn() is not enabled. Is this a related bug? or is something not right with my setup? Here is a simplified example of my index setup in scout.php with splitting enabled that doesn't work with deleting entries from the Algolia index: return [
'indices' => [
\rias\scout\ScoutIndex::create($allIndexName)
// Scout uses this by default, so this is optional
->elementType(\craft\elements\Entry::class)
// If you don't define a siteId, the primary site is used
->criteria(function (\craft\elements\db\EntryQuery $query) {
return $query
->section([
'pages',
'newsAndInsights',
'people',
'practices',
'services',
'resources'
]);
})
/*
* The element gets passed into the transform function, you can omit this
* and Scout will use the \rias\scout\ElementTransformer class instead
*/
->transformer(function (\craft\elements\Entry $entry) {
$pagesIndexName = 'Pages';
$practicesServicesIndexName = 'Practices/Services';
$peopleIndexName = 'People';
$newsIndexName = 'News & Insights';
$resourcesIndexName = 'Resources';
if ($entry->section->handle == 'pages'):
return [
'title' => $entry->title,
'permalink' => $entry->url,
'description' => $entry->contentSummary,
'defaultSortBy' => $entry->title,
'index' => $pagesIndexName
];
elseif ($entry->section->handle == 'newsAndInsights'):
return [
'title' => $entry->title,
'description' => $entry->contentSummary,
'article_content' => ['some', 'content', 'from', 'a', 'matrix'],
'post_date' => array(
'lvl0' => $entry->postDate->format('Y'),
'lvl1' => $entry->postDate->format('Y > F')
),
'post_date_timestamp' => $entry->postDate->getTimestamp(),
'post_date_formatted' => $entry->postDate->format('m.d.Y'),
'permalink' => $entry->url,
'defaultSortBy' => $entry->postDate->getTimestamp(),
'index' => $newsIndexName
];
elseif ($entry->section->handle == 'people'):
// Change data so we can filter out later by if the person is
// a redirected entry type.
if ($entry->type->handle == 'redirected') {
return [
'name' => $entry->title,
'entryType' => $entry->type->handle,
'index' => $peopleIndexName
];
}
return [
'objectID' => $entry->id,
'entryType' => $entry->type->handle,
'name' => $entry->title,
'last_name' => $entry->peopleLastName,
'first_name' => $entry->peopleFirstName . (!empty($entry->peopleMiddleName) ? ' ' . $entry->peopleMiddleName : ''),
'position' => $entry->peoplePosition2->label,
'email' => $entry->peopleEmail,
'level' => $entry->peopleTitle3->exists() ? $entry->peopleTitle3->one()->title : null,
'image' => $entry->peopleHeadshot->exists() ? $entry->peopleHeadshot->one()->optimize5x4->src() : null,
'permalink' => $entry->url,
'defaultSortBy' => $entry->peopleLastName . ' ' . $entry->peopleFirstName . (!empty($entry->peopleMiddleName) ? ' ' . $entry->peopleMiddleName : ''),
'index' => $peopleIndexName
];
elseif ($entry->section->handle == 'practices' || $entry->section->handle == 'services'):
return [
'title' => $entry->title,
'status' => $entry->status,
'permalink' => $entry->url,
'description' => $entry->contentSummary,
'defaultSortBy' => $entry->title,
'index' => $practicesServicesIndexName
];
elseif ($entry->section->handle == 'resources'):
// Remove from index if there isn't a related asset.
if (!$entry->resourceAsset1->exists()) {
return [];
}
return [
'objectID' => $entry->id,
'title' => $entry->title,
'description' => $entry->contentSummary,
'permalink' => $entry->resourceAsset1->exists() ? $entry->resourceAsset1->one()->url : null,
'defaultSortBy' => $entry->title,
'index' => $resourcesIndexName
];
endif;
})
->splitElementsOn([
'article_content'
])
/*
* You can use this to define index settings that get synced when you call
* the ./craft scout/settings/update console command. This way you can
* keep your index settings in source control. The IndexSettings
* object provides autocompletion for all Algolia's settings
*/
->indexSettings()
]
]; |
I'm having the same problem when unpublishing an entry doesn't remove it from the algolia index. I understand that I could use ->status() in the criteria and then filter by a status facet on the front-end as per tehtrav's comment, but I'm a little weary about potentially exposing unpublished content to exploits on the front end. Is there a recommended workaround? I think the problem is that the MakeSearchableJob bails here if it can't find the element (which it won't do, assuming you don't have I wonder if somewhere down the chain if should add a DeIndex job, something like this psuedo-code
That raises another question - if an entry is updated and no longer matches the criteria, is it it removed from the index? My tests don't show that it is. Eg. if I have a lightswitch field, ->criteria(fn(EntryQuery $query) => $query->showInSearch(true)) And I toggle the field then save the element, the element isn't removed from the index. This seems like a fairly big bug, unless I've overlooked something or misunderstood the usage? |
Hey @MangoMarcus Thanks for bumping this issue. I'm looking at a similar bug in #281, and your pseudo-code could be a good starter for a fix. I gather you're seeing the issue regardless of wether your using |
Hey @janhenckens , thanks for the speedy response, I've subscribed for that bug now. I'm not using |
I am having the same issue here. When an element is deleted, it is not removed from Algolia automatically. I had to add a afterDelete hook to make sure they are deleted.
Still having an issue with records that have EDIT : If the element is
|
@mathg Could you try the fix I mentioned here and report back if that fixes things? #281 (comment) |
@janhenckens Hijacking this thread to add some findings. The above custom It would be great if Scout could check this in some way and use the correct filter syntax accordingly. |
Hey @low Scout doesn't currently track objectIds and assumes the default elementId (which obviously isn't always correct). I don't think I want to add the tracking for that in the Craft database, so maybe a clean example in the docs in case someone is using anything other then elementId could be a work around? |
I'm running into this issue now, for the same reason @twosixcode was, I'm appending the site handle on to the end of my In the craft-scout/src/engines/AlgoliaEngine.php Line 48 in e59aa31
I'm curious if there's a reason that step is excluded from the If this bit in craft-scout/src/engines/AlgoliaEngine.php Lines 66 to 72 in e59aa31
was replaced with
it has my custom Perhaps it is because transforming could potentially be expensive, with things like image transforms, etc, and normally wouldn't be necessary when deleting? |
Getting this too with a pretty simple scout setup. It looks like deleting entries or setting them to disabled doesn't remove them from the index. What is the workaround for this? I tried with split elements and this didn't seem to work.
Any ideas? Thanks! |
Hey @harry2909 I'm not sure if this is the best approach, but here is how I got around this issue. I set up a couple event handlers
That
... basically just manually deleting the object (using my customized objectId) when an entry is deleted... And the
which manually removes the entry from Algolia (again, using my custom Seems to be working for me. I do see multiple deletes come in to Algolia, one still for the plain numeric Hope that is helpful! |
Thanks @GaryReckard I'll give that a try! |
I have
sync
set totrue
and my criteria look like thisBecause I am indexing all sites, I can not rely on Entry ID as Object ID (because the same entry exists in multiple languages). If I do not use a unique Object ID I end up overwriting the record with whatever language was most recently saved. So I have a transformer that creates a unique Object ID by appending the locale slug to the entry id like this
'objectID' => $entry->id .'-'. $entry->locale,
This allows me to have all of my records in the same Algolia index.Scout works perfectly, firing on entry save when entries have a status of
enabled
. However if I set an entry status todisabled
Scout does not fire on entry save and my Algolia index is not updated.Similarly, if I Delete an entry from Craft, the index item is not removed from Algolia (regardless of the current status of the entry).
It appears the unique Object ID approach I am using is causing Scout not to remove the item from the index when disabled or deleted. If I use Entry Id as ObjectId the deleted or disabled entries are removed as expected.
Is there a way around this (other than separating every Craft Site into a different index)? Or relying on periodic batch indexing instead of sync on entry save? For example a Scout Event that I could hook into with a small custom Module where I could transform the ObjectId so that removal of an item from the index will find a match and succeed?
The text was updated successfully, but these errors were encountered: