Hi,
when:

  • I use the excerpt in my view
  • In the index=>processors=>Highlight=>Exclude fields from excerpt: I have not checked Field A and Field B
  • I have checked Field C (so it´s excluded)
  • I search for "searchterm" which is in Field A and not in Field B
  • Field A AND Field B is displayed in the excerpt

Expected behaviour:
Do not display fields in my excerpt that does not match with "searchterm".

Furtheron:

When Field B has multiple values - for example when Field B is the linkname in a referenced entity, and there are 4 entities attached, the excerpt will show all 4 linknames. Only thing needed is
- a match of "searchterm" in one of the referenced linknames
- or a match of searchtearm in Field A

But maybe: Someone wants to display a field in the excerpt as a standard output - even when this field has no match. If this was the intention it´s not working fine also. Because:
When I do not have ANY matches of "searchterm" in one of the unchecked fields:
Those unchecked fields are not displayed.
For example: "searchterm" is in Field C : the excerpt is empty.
If someone wants to have a standard output of a given field, which has no match, he should put this field into his view or use replacement patterns in the rewrite results section of the views excerpt field.

I try to make a figure:

in SOLR, this is how my linkname field is stored (In Our example "Field A"). The linkname field is part of the node attached via entity reference field:
( Entity Reference Field) » Content » Call to action » Link text (title_3)

"tm_X3b_en_X2d_SG_title_3":
          ["CTA1BCDshowertest",
          "Learn more CTA2",
          "Learn more CTA3a",
          "CTA 5a"],

When I search for "showertest", the excerpt displays:
CTA1BCDshowertest … Learn more CTA2 … Learn more CTA3a … CTA 5a … Learn more CTA4a … Learn more CTA4b … CTA 6a … CTA7a … CTA8a …

The italic part is coming from my Field B:
( Entity Reference Field) » Content » (Field in the attached node) » Paragraph » Call to action » Link text (title_5)

"tm_X3b_en_X2d_SG_title_5":
          ["Learn more CTA4a",
          "Learn more CTA4b",
          "CTA 6a",
          "CTA7a",
          "CTA8a"],

And when I have a match in Field C - in my case it´s the summary field: The excerpt is empty.
(Summary (field_summary)):
"tm_X3b_en_X2d_SG_field_summary":["Teaser Showertest ...stripped text..."],

Here´s the spell of this node:

spell":["Teaser Showertest ...stripped text...",
          ...stripped other fields...
          "CTA1BCDshowertest",
          "Learn more CTA2",
          "Learn more CTA3a",
          "CTA 5a",
          "Learn more CTA4a",
          "Learn more CTA4b",
          "CTA 6a",
          "CTA7a",
          "CTA8a"],

How can i make it, that only the values are in the excerpt which have matched "showertest" ?
(the excerpt should display only CTA1BCDshowertest)
Greetings,
Lars

P.S.: I hope i am in the right module and it´s not a search_api or views issue. If it so, forgive me and move to them :-D

Issue fork search_api-3031390

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

Synflag created an issue. See original summary.

mkalkbrenner’s picture

The excerpt can be produced by Search API. Per default the all data is fetched from the database unless you enable "Retrieve highlighted snippets". Did you enable this option?

If this doesn't solve your issue, enable search_api_solr_debug and check the raw result from Solr. There should be a highlighting section. Does this one look correct?

synflag’s picture

Yes, i played with "Retrieve highlighted snippets" (and most other options) and actually I plan to have it enabled.
By the way I use SOLR 7.6 and I will enable search_api_solr_devel (Eventually I have to do this tomorrow). Thx for the reply.

synflag’s picture

Good morning.
this is what is written as info on my views searchpage:
I tried to simplify the output and deleted most not interestig fields and same fields in other languages. Basically:
title_3 is FIELD A
title_5 is FIELD B
field_summary is FIELD C

POST => Array
(
    [omitHeader] => Array
        (
            [0] => true
        )

    [wt] => Array
        (
            [0] => json
        )

    [json.nl] => Array
        (
            [0] => flat
        )

    [q] => Array
        (
            [0] => ((..... tm_X3b_en_field_summary:"showertest"^2  tm_X3b_en_title_3:"showertest" tm_X3b_en_title_5:"showertest") (... stripped other languages...))
        )

    [start] => Array
        (
            [0] => 0
        )

    [rows] => Array
        (
            [0] => 1000000
        )

    [fl] => Array
        (
            [0] => tm_X3b_en_field_summary,.....tm_X3b_en_title_3.....tm_X3b_en_title_5.....ss_search_api_id,ss_search_api_language,score
        )

    [fq] => Array
        (
            [0] => (ss_search_api_language:"en" ss_search_api_language:"th" ss_search_api_language:"pl" ss_search_api_language:"en-SG" ss_search_api_language:"th-TH" ss_search_api_language:"und" ss_search_api_language:"zxx")
            [1] => +index_id:test_lj_solr_index +hash:ht4cq9
        )

    [hl] => Array
        (
            [0] => true
        )

    [hl.fl] => Array
        (
            [0] => ..... tm_X3b_en_field_summary, ..... tm_X3b_en_title_3, ..... tm_X3b_en_title_5
        )

    [hl.snippets] => Array
        (
            [0] => 3
        )

    [hl.fragsize] => Array
        (
            [0] => 0
        )

    [hl.mergeContiguous] => Array
        (
            [0] => false
        )

    [hl.requireFieldMatch] => Array
        (
            [0] => true
        )

    [hl.simple.pre] => Array
        (
            [0] => [HIGHLIGHT]
        )

    [hl.simple.post] => Array
        (
            [0] => [/HIGHLIGHT]
        )

    [hl.highlightMultiTerm] => Array
        (
            [0] => false
        )

)

This is what I get from the debug log message from search_api_solr_devel:

{
  "response":{"numFound":1,"start":0,"maxScore":4.182892,"docs":[
      {
        "tm_X3b_en_X2d_SG_field_summary":["Teaser Showertest Everything ....."],
        "tm_X3b_en_X2d_SG_title_3":["CTA1BCDshowertest",
          "Learn more CTA2",
          "Learn more CTA3a",
          "CTA 5a"],
        "tm_X3b_en_X2d_SG_title_5":["Learn more CTA4a",
          "Learn more CTA4b",
          "CTA 6a",
          "CTA7a",
          "CTA8a"],
        "ss_search_api_id":"entity:node/1061:en-SG",
        "ss_search_api_language":"en-SG",
        "score":4.182892}]
  },
  "highlighting":{
    "ht4cq9-test_lj_solr_index-entity:node/1061:en-SG":{
      "tm_X3b_en_X2d_SG_field_summary":["Teaser [HIGHLIGHT]Showertest[/HIGHLIGHT] Everything ....."]}}}

Is it ok that I only get a Highlighted snippet ofthe summary field and not "tm_X3b_en_X2d_SG_title_3":["CTA1BCDshowertest", "Learn more CTA2", "Learn more CTA3a", "CTA 5a"], ?

mkalkbrenner’s picture

Category: Bug report » Support request

You search for "showertest". The only field that matches is tm_X3b_en_X2d_SG_field_summary.
The Highlighter could be configured to highlight only the matched fields or any returned fields.

In your case, where only tm_X3b_en_X2d_SG_field_summary returns a highlighted snippet, the excerpt shhould only consist of this. If you see more fragments, the highlight processor of Search API ignored Solr's response and added results from the database. We need to figure out, why that happens in your case and if it is a bug. Which search_api version are you using?

synflag’s picture

Category: Support request » Bug report

OK, i did manage to get "tm_X3b_en_X2d_SG_title_3":["CTA1BCD [HIGHLIGHT]Showertest[/HIGHLIGHT]"]} by doing a space before Showertest.

the search api version is 8.x-1.11

My excerpt still shows:
… CTA1BCD Showertest … Learn more CTA2 … Learn more CTA3a … CTA 5a … Learn more CTA4a … Learn more CTA4b … CTA 6a … CTA7a … CTA8a …
title_3 (FIELD A)=> bold
title_5 (FIELD B)=> italic

When I delete "Showertest" from "CTA1BCD Showertest":
Response from SOLR:
"highlighting":{ "ht4cq9-test_lj_solr_index-entity:node/1061:en-SG":{ "tm_X3b_en_X2d_SG_field_summary":["Teaser [HIGHLIGHT]Showertest[/HIGHLIGHT] Everything ..... ]}}}
The excerpt is empty.
This is a expected and wanted behaviour. But when I now go to:
index=>processors=>Highlight=>Exclude fields from excerpt
and uncheck Summary (field_summary) this is my excerpt:
… Teaser Showertest Everything ....CTA1BCD … Learn more CTA2 … Learn more CTA3a … CTA 5a … Learn more CTA4a … Learn more CTA4b … CTA …

title_3 (FIELD A)=> bold and italic
title_5 (FIELD B)=> italic
field_summary (FIELD C) => bold

Sidenote: in the excerpt all matches of "showertest" were highlighted correctly - no matter if I wrote in title_3 "CTA1BCD Showertest" or without space "CTA1BCD:showertest"

synflag’s picture

Hi, I see that I have accidentally set back the "support request" to a a "bug report". This was not my intention - I only commented it and the system made-again- a bug report of this.
But What should I do now?
Are we clear, that it is not a bug? The xecerpt still shows values without matches.
Will I mix up things when I set it back to "support request"??
Greetings
Lars

googletorp’s picture

Project: Search API Solr » Search API
Version: 8.x-2.5 » 8.x-1.x-dev
Component: Code » User interface
Issue tags: +search api solr
StatusFileSize
new2.89 KB

I'm moving this ticket to Search API issue queue, as the issue is in the search api module it self.

The core issue is in `Drupal\search_api\Plugin\search_api\processor\Highlight` where this code snippet can be found:

/**
   * Adds excerpts to all results, if possible.
   *
   * @param \Drupal\search_api\Item\ItemInterface[] $results
   *   The result items to which excerpts should be added.
   * @param string[] $fulltext_fields
   *   The fulltext fields from which the excerpt should be created.
   * @param array $keys
   *   The search keys to use for highlighting.
   */
  protected function addExcerpts(array $results, array $fulltext_fields, array $keys) {
    $items = $this->getFulltextFields($results, $fulltext_fields);
    foreach ($items as $item_id => $item) {
      $text = [];
      foreach ($item as $values) {
        $text = array_merge($text, $values);
      }
      $item_keys = $keys;

      // If the backend already did highlighting and told us the exact keys it
      // found in the item's text values, we can use those for our own
      // highlighting. This will help us take stemming, transliteration, etc.
      // into account properly.
      $highlighted_keys = $results[$item_id]->getExtraData('highlighted_keys');
      if ($highlighted_keys) {
        $item_keys = array_unique(array_merge($keys, $highlighted_keys));
      }

      // @todo This is pretty poor handling for the borders between different
      //   values/fields. Better would be to pass an array and have proper
      //   handling of this in createExcerpt(), ensuring that no snippet goes
      //   across multiple values/fields.
      $results[$item_id]->setExcerpt($this->createExcerpt(implode($this->getEllipses()[1], $text), $item_keys));
    }
  }

From a Search API Solr perspective, the problem here is that in $results, each result will have information about the highlighted keys and the fields that has the highlights. This data is located in `highlighted_keys` and `highlighted_fields` in the extraData property. While `highlighted_keys` is being used, `highlighted_fields` is not. The result is that all fields which can contain highlights are being shown.

I have attached a patch that fixes this for Solr, but I'm not sure if this can provide issues for other search backends. The main idea here is to get the fields which contains highlights (this will often not be the same list of fields for all results).

I had the same problem as the OP and applying attached patch fixes the issues I had.

googletorp’s picture

Component: User interface » Plugins
drunken monkey’s picture

Issue tags: -search api solr

I think the cause of this bug is already described right there in addExcerpts():

      // @todo This is pretty poor handling for the borders between different
      //   values/fields. Better would be to pass an array and have proper
      //   handling of this in createExcerpt(), ensuring that no snippet goes
      //   across multiple values/fields.

So, I think the proper solution would just be to implement that idea. Could you try that?
The current approach in #8 is interesting, but as the highlighted_fields extra data is something completely different and doesn’t necessarily obey the same rules as the excerpt, I don’t think adding this makes sense here. (In any case, it would have to fall back to $fulltext_fields if not present, and also use array_intersect() so fields can be excluded properly from the excerpt.)

PS: It seems you (like many others – it's really easy to misinterpret) are confused by the "Issue tags" field. As the guidelines state, they aren't meant for free text tags related to the issue, but only for specific categorization purposes, usually by module maintainers.
So, if you aren't sure your current usage is correct, please just leave the field empty.

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

tuwebo’s picture

I am working on 3031390-excerpt-shows-all-fields fork:
- Trying to solve handling for the borders between different values/fields
- Bypassing merging $keys if the backend found $highlighted_keys.
- PoC: For rendering the excerpt field names as part of the excerpt. It might be useful to know where the excerpt came from.

Any review/contribution will be very welcome.

tuwebo’s picture

I am adding two related issues for this one work properly.
- #3536089: Replace deprecated REQUIREMENT_ERROR constant in search_api_db_defaults_requirements() for Drupal 11+ compatibility
will solve the failing test search_api_db_defaults\Functional\IntegrationTest::testInstallAndDefaultSetupWorking in this MR.
- #3110348: Values overwritten when multiple aggregated fields exist on same data source
is needed for taking into account any aggregated_fields in the excerpt.

I think the only task pending could be a hook_update for updating indexes configuration to include:
$processors['highlight']['settings']['include_field_labels'] = FALSE;

tuwebo’s picture

Status: Active » Needs review
StatusFileSize
new371.73 KB
new376.24 KB

I've merged the issue branch with the latest changes from 8.x-1.x (which includes around ~12 commits), so the only test that was failing now passes. All tests are passing and pipelines run with no issues.
Any review will be very welcome.

There are some test added and new configuration for the Highlight processor to be able to show the field labels, since it helps the user to spot where the snippets are coming from.
See attached images: "drupal-search-api-3031390-15-01" and "drupal-search-api-3031390-15-02"

drunken monkey’s picture

Status: Needs review » Needs work

Amazing work, thank you very much!
I left some comments in the MR and did some refactoring according to my personal preferences (plus minor code style fixes) but mostly this looks very good already. And thanks to our exhaustive test coverage I think we can be reasonably sure that all of this is working as it should.
The only things that still need to be addresses are the two unrelated features you added, which will need to be either ironed out or split into separate tickets, whichever you prefer. (See the unresolved threads in the MR.)

In any case, thanks a lot again!

tuwebo’s picture

Wow thank you so much for the review. I'll go through the MR comments and try to reply there, afterwards create a summary here in a new comment if necessary.
If for some reason (mostly lacking of time) you don't see me taking some action this week, please feel free to go ahead with whatever better suit the search api module needs.

Thank you!

drunken monkey’s picture

Status: Needs work » Needs review

I split both of the new features into their own issues, I think this is probably easier to work with and should definitely make more sense when reviewing these changes in the future.
If you are fine with that, I think we can merge this one.

In any case, thanks a lot again for all your work on this, sorry I had to complicate things with the new issues.

(There is still one open thread in the MR, but I’d just mark that “resolved” if you don’t have any suggestions, either.)

tuwebo’s picture

Thank you very much for the review, I understand better now, and I totally agree to split the new features. I'll try to look at them in the coming days.

drunken monkey’s picture

Great, thanks!
So, do you agree this is RTBC now, can I merge it?

tuwebo’s picture

Yes, let's do it

tuwebo’s picture

I've just realized that config/schema/search_api.processor.schema.yml does no longer need include_field_labels, since we have a separate issue for it #3543631: Optionally add field labels to excerpt snippets

drunken monkey’s picture

Status: Needs review » Fixed

Thanks, good catch!
Fixed that and merged.
Thanks a lot again, was a pleasure working with you on this!

Status: Fixed » Closed (fixed)

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

pbouchereau’s picture

Hello.

So the createExcerpt() method in the Highlight processor plugin was "removed" on 8.x-1.39 by throwing "SearchApiException('This method has been removed.')" and with the comment "@todo Remove for version 2.0.0."

IMO this "removal" was very poorly handled. If it's supposed to be removed in the next major version then it has to be deprecated in the previous one, not awkwardly disabled right away.

The method is private but the class isn't final...

smustgrave’s picture

FYI this caused a regression where our excerpts no longer fully appear. Reverting to 8.x-1.38 fixed the problem. Think this should of been a configuration option vs just removing.

tomefa’s picture

Some problem for us, this caused a regression where our excerpts no longer appear at all.
Reverting to 8.x-1.38 fixed the problem.