Problem/Motivation
I am unable to render fields using the SearchApiEntityField plugin in views, even when the search query returns a result. I am using search_api_opensearch as the back end.
Tracking this down I think this is because, in SearchAPIEntityField there are the following lines in getItems:
if ($values->search_api_datasource != $this->getDatasourceId()) {
return [];
}
Inspecting $values I see that $values->search_api_datasource is an array of one data source id whereas $this->getDatasourceId() is a string. The data source ids to match. I don't know whether search_api_datasource should not be an array, or whether the if statement is incorrect.
Remaining tasks
| Comment | File | Size | Author |
|---|---|---|---|
| #19 | 3262507-19--views_ignore_lazy_load_fields.patch | 2.87 KB | drunken monkey |
Issue fork search_api-3262507
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
Comment #2
rlmumfordDigging further, it looks like search_api_datasource is not expected to be set on the ResultRow directly at all but rather would be lazy loaded when required by
\Drupal\search_api\Plugin\views\ResultRow. A solution might therefore be to not copy these fields on to the ResultRow if they are returned by the Backend.Comment #4
rlmumfordAdded a MR that resolves my problem, I'm not sure whether this should be something that should be fixed in the backend providers or here though. Another alternative would be to replace the checks on `$values->search_api_datasource` with explicit checks on `$values->_item->getDatasourceId()`
Comment #5
rlmumfordAdding a patch file as the test bot doesn't seem to like merge requests.
Comment #6
acbramley commentedHaving the same issue, it also throws an exception when using a rendered entity because
isValidDatasourceis called with an array rather than a string which throws an exception.EDIT: Should mention patch #5 fixed it for me :)
Comment #7
kalpaitch commentedI'm having the same issue, and patch #5 does solve the issue for me too.
I wonder if we could avoid the duplication of configured fields a bit by adding a getLazyLoadFields() method or some such to ResultRow instead of re-creating the array in SearchApiQuery?
I mention because the solution used in patch #5 is used once already in SearchApiQuery::addField(), so we're duplicating this twice in the same file...
Comment #8
kalpaitch commentedI think this is the best approach which brings the two existing methods together with minimal impact on additional classes and methods.
There are only 2 calls to
getFields()methods in the SearchApiQuery class so I think this covers all use cases for now.Comment #10
kalpaitch commentedComment #11
acbramley commentedDoes that mean these fields shouldn't be indexed in the first place? If so we can simply stop search_api_opensearch indexing them here
Comment #12
kalpaitch commented@acbramley That might also be the case. Either way this patch still seems necessary, they're not fields that views should be querying.
It might be worth referring comment #11 back to #3267797: Indexed Fields in views empty, to see if any work is actually needed there.
Comment #13
pebosi commented#10 works for me
Comment #14
kalpaitch commented@pebosi could you mark as reviewed pls? (assuming you have)
Comment #15
varshith commentedThe patch at #10 works fine.
The code is pretty straightforward and I am marking it as reviewed.
Comment #16
acbramley commentedRerolled
Comment #17
acbramley commentedReroll, the
list()change was already committed.Comment #18
longwaveI found this issue via #3313519: TypeError: Illegal offset type in isset or empty in Drupal\search_api\Entity\Index->isValidDatasource() when using rendered item field
What is the purpose of putting
search_api_id,search_api_datasourceandsearch_api_languageinto the index in the first place? An alternative fix is to skip indexing these items at all in the OpenSearch case, and that seems to work with no side effects for my use case.Comment #19
drunken monkeyThanks a lot for posting this, and sorry it took me such a long time to reply.
The patch looks pretty good and the problem seems real, based on the feedback. (I’m not using the Search API OpenSearch module myself.)
Also, indexing those fields migth be necessary, as
\Drupal\search_api\Query\QueryInterface::sort()specifies that it should be possible to sort by them. (Filtering by language or datasource is also allowed.) In my opinion, the returned result items should still not include those fields (as they are not configured fields on the index), so a fix to the Search API OpenSearch module might be in order, too, but it definitely cannot hurt to guard against this problem here, too.However, if
$this->ignoredFieldValuesis never written to anyways, couldn’t it just be a constant?Furthermore, why not just make
\Drupal\search_api\Plugin\views\ResultRow::$lazyLoadpublic (or a constant) and use that directly?Patch attached, please review. (Would probably need a change record, too, though, in this form, due to the deprecation of
\Drupal\search_api\Plugin\views\ResultRow::$lazyLoad. (Only relevant for any sub-classes of\Drupal\search_api\Plugin\views\ResultRow, but still.)Comment #20
bobooon commented+1 RTBC #19
Using search_api and search_api_opensearch with this patch resolved the fatal errors that were happening on search.
Comment #22
drunken monkeyThanks for testing and reporting back, good to hear this worked! (And even fixed a fatal error, in your case!)
Committed the patch and posted a change record.
Thanks again, everyone!