Fix search in documents for hierarchical documents like newspaper.

== Current Situation

The search plugin has the option to restrict the search in current
document and/or in current collection. This can be used to place the
plugin on a separate page to search only in one collection. Or you place
the plugin on the workview page and trigger a search in document.

Of course, the SearchInDocument plugin is better suited for the workview as the results are reported by via AJAX and the visitor will stay on the current page.

On the opposite, using the search plugin makes it possible to search
in all issues of a newspaper year or even a full newspaper title. At
least, this should be possible. The current implementation does not work
as expected.

=== Example

==== Search plugin on workview (issue)

For example, you can place the plugin on level of a newspaper issue. If
you launch a search, the current implementation will search not only in
current issue but in all issues of the current year. This is a
frequently demanded feature but works only by hasard.

newspaper title (anchor)
   |
   |-> year
        |
        |-> Issue

The current search plugin does two mistakes:

1. Instead of the current document uid, the parent uid is set.
2. The search is done in given uid and all children.

==== Search plugin on workview (year/anchor)

If you place the search plugin on the workview with calendar view, the
search fails.

Same procedure as above. The search will be done in the anchor and it's
children (years). All these files have no fulltexts. So the result is
always empty.

== Proposed Implementation

The proposed implementation does change the searchIn document limitation
of the search plugin to search in current document _and_ all it's children.

This is done on using Solr join feature. To make this possible, the
partof field must use the docValues feature as "uid" does it already.
This commit is contained in:
Alexander Bigga 2020-11-20 16:16:48 +01:00
parent a12df1d4e1
commit d312b1d8ee
4 changed files with 17 additions and 15 deletions

View File

@ -324,12 +324,6 @@ class Solr
$params['filterquery'] = isset($params['filterquery']) ? $params['filterquery'] : [];
// Restrict the fields to the required ones.
$params['fields'] = 'uid,id';
// Extend filter query to get all documents with the same uids.
foreach ($params['filterquery'] as $key => $value) {
if (isset($value['query'])) {
$params['filterquery'][$key]['query'] = '{!join from=uid to=uid}' . $value['query'];
}
}
// Set filter query to just get toplevel documents.
$params['filterquery'][] = ['query' => 'toplevel:true'];
// Set join query to get all documents with the same uids.

View File

@ -117,19 +117,26 @@ class Search extends \Kitodo\Dlf\Common\AbstractPlugin
&& \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->piVars['id'])
) {
$this->loadDocument();
// Get document's UID or parent ID.
// Get document's UID
if ($this->doc->ready) {
return '<input type="hidden" name="' . $this->prefixId . '[id]" value="' . ($this->doc->parentId > 0 ? $this->doc->parentId : $this->doc->uid) . '" />';
return '<input type="hidden" name="' . $this->prefixId . '[id]" value="' . ($this->doc->uid) . '" />';
}
} elseif (!empty($list->metadata['options']['params']['filterquery'])) {
// Get document's UID from search metadata.
// The string may be e.g. "{!join from=uid to=partof}uid:{!join from=uid to=partof}uid:2503"
foreach ($list->metadata['options']['params']['filterquery'] as $facet) {
$facetKeyVal = explode(':', $facet['query']);
if ($facetKeyVal[0] == 'uid') {
$documentId = (int) substr($facetKeyVal[1], 1, strpos($facetKeyVal[1], ')'));
for ($j=0; $j < count($facetKeyVal); $j++) {
if (preg_match('/uid$/', $facetKeyVal[$j])) {
if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($facetKeyVal[$j+1])) {
$documentId = (int) $facetKeyVal[$j+1];
}
}
}
}
return '<input type="hidden" name="' . $this->prefixId . '[id]" value="' . $documentId . '" />';
if (!empty($documentId)) {
return '<input type="hidden" name="' . $this->prefixId . '[id]" value="' . $documentId . '" />';
}
}
return '';
}
@ -453,7 +460,8 @@ class Search extends \Kitodo\Dlf\Common\AbstractPlugin
!empty($this->piVars['id'])
&& \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->piVars['id'])
) {
$params['filterquery'][]['query'] = 'uid:(' . $this->piVars['id'] . ') OR partof:(' . $this->piVars['id'] . ')';
// search in document and all children
$params['filterquery'][]['query'] = '{!join from=uid to=partof}uid:{!join from=uid to=partof}uid:' . $this->piVars['id'];
$label .= htmlspecialchars(sprintf($this->pi_getLL('in', ''), Document::getTitle($this->piVars['id'])));
}
}

View File

@ -108,7 +108,7 @@ limitations under the License.
<!-- Image number where this document starts. -->
<field name="page" type="int" indexed="false" stored="true" required="true" default="0" />
<!-- Unique identifier for the parent document in the TYPO3 database. Only if this is a multi-volume work! -->
<field name="partof" type="int" indexed="true" stored="true" required="true" default="0" />
<field name="partof" type="int" indexed="true" stored="true" required="true" default="0" docValues="true" />
<!-- Unique identifier for the root document in the TYPO3 database. Only if this is a multi-volume work! -->
<field name="root" type="int" indexed="true" stored="true" required="true" default="0" />
<!-- XML ID of this document in the METS file. This is only unique within the METS file! -->

View File

@ -28,7 +28,7 @@
<label index="tt_content.pi_flexform.collections">Restrict search to these collections</label>
<label index="tt_content.pi_flexform.searchIn">Restrict search to current document or collection?</label>
<label index="tt_content.pi_flexform.searchIn.none">none</label>
<label index="tt_content.pi_flexform.searchIn.document">document only</label>
<label index="tt_content.pi_flexform.searchIn.document">document and children only</label>
<label index="tt_content.pi_flexform.searchIn.collection">collection only</label>
<label index="tt_content.pi_flexform.searchIn.all">both</label>
<label index="tt_content.pi_flexform.facets">Show these facets</label>
@ -71,7 +71,7 @@
<label index="tt_content.pi_flexform.collections">Suche auf diese Kollektionen einschränken</label>
<label index="tt_content.pi_flexform.searchIn">Suche auf aktuelle/s Kollektion/Dokument einschränken?</label>
<label index="tt_content.pi_flexform.searchIn.none">nein</label>
<label index="tt_content.pi_flexform.searchIn.document">nur Dokument</label>
<label index="tt_content.pi_flexform.searchIn.document">nur Dokument und Kindelemente</label>
<label index="tt_content.pi_flexform.searchIn.collection">nur Kollektion</label>
<label index="tt_content.pi_flexform.searchIn.all">beides</label>
<label index="tt_content.pi_flexform.facets">Diese Facetten anzeigen</label>