Skip to content
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

Mulitvalued custom field results are incomplete #40

Open
kwiechmann opened this issue Jan 13, 2021 · 1 comment · May be fixed by #46
Open

Mulitvalued custom field results are incomplete #40

kwiechmann opened this issue Jan 13, 2021 · 1 comment · May be fixed by #46
Assignees
Labels
bug Something isn't working needs review/QA Waiting for someone to validate

Comments

@kwiechmann
Copy link

Original request was opened here: https://www.drupal.org/project/graphql_search_api/issues/3183710 @Kyubbi instructed to open here on github instead of Drupal.org

Hi! I would appreciate some guidance from someone that has already been there and has the battle scars to share. AdvThanksance!!!

The module stack is pretty tall and it has been difficult to narrow down any further. Looking into the Common pitfalls and FAQs has not led to any inspiration. I thought to post now but I will look at upgrading to the latest recommended versions of the module. Previous recommendations to upgrade to search_aol_solr to 4.1 from 8.x-1.5 did not resulted in any improvement.

Givens:

  • Created a custom field (group__members) to include data for indexing and faceting in Solr.
  • The required data resides outside of the basic content type.
  • The source of data for the custom field is a multi-valued set of names.
  • The search results should also return a multi-valued set of names.

Knowns:

  • Able to index into Solr. See Evidence 2.
  • As a positive, able to get results with facets using graphql_search_api. See Evidence 3.
  • The custom field is not unpacked correctly. In GraphQL Explorer, it is returning just the first name as a single string instead of a multi-valued set.

Relevant versions and enabled modules:

  • Apache Solr 4.5.1
  • Drupal core 8.8.8 (Upgrade to 8.9 scheduled)
  • search_api 8.x-1.18 (Up-to-date)
  • search_api_solr 4.1.10 (Up-to-date)
  • search_api_solr_legacy 4.1.10 (Up-to-date)
  • graphql 8.x-3.1 (Up-to-date)
  • graphql_search_api 8.x-1.2 (Up-to-date)

Evidence 1: Custom field definition

namespace Drupal\brqc_custom\Plugin\search_api\processor;

use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Processor\ProcessorProperty;

/**
 * Adds a custom field to the indexed data.
 *
 * @SearchApiProcessor(
 *   id = "group__members",
 *   label = @Translation("Group Members"),
 *   description = @Translation("Add a custom field of group members to search index."),
 *   stages = {
 *     "add_properties" = 0,
 *   },
 *   locked = true,
 *   hidden = false,
 * )
 */
class GroupMembers extends ProcessorPluginBase {

  /**
   * machine name of the processor.
   * @var string
   */
  protected $processor_id = 'group__members';

  /**
   * {@inheritdoc}
   */
  public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) {
    $properties = array();

    if (!$datasource) {
      $definition = array(
        'label' => $this->t('Group Members'),
        'description' => $this->t('Custom field for storing all members that belong to this group.'),
        'type' => 'string',
        'processor_id' => $this->getPluginId(),
      );
      $properties[$this->processor_id] = new ProcessorProperty($definition);
    }

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public function addFieldValues(ItemInterface $item) {
    $entity = $item->getOriginalObject()->getValue();
    $entity_type = $entity->getEntityTypeId();

    // Use $entity to get custom field.
    // Determine the correct content type.
    if ($entity_type == 'group') {
      // Get members from the group. Temporarily using superhero secret identities.
      $members = [
        'John Doe',
        'Peter Parker',
        'Bruce Wayne',
        'Clark Kent',
        'Diana Prince',
        'Arthur Curry',
        'Jack Napier',
        'James Howlett',
      ];
      $temp_members = [];
      $random = rand(0, count($members));
      $member_keys = array_rand($members, $random);
      if (!is_array($member_keys)) {
        $temp_members[] = $members[$member_keys];
      }
      else {
        foreach ($member_keys as $member_key) {
          $temp_members[] = $members[$member_key];
        }
      }
      $members = $temp_members;

      // Add the group members in individually.
      if (count($members) > 0) {
        $fields = $this->getFieldsHelper()
          ->filterForPropertyPath($item->getFields(), NULL, $this->processor_id);
        foreach ($fields as $field) {
          foreach ($members as $member) {
            $field->addValue($member);
          }
        }
      }
    }
  }

}

Evidence 2: Selected portions of query results from Solr admin.

{
  "response": {
    "numFound": 1,
    "start": 0,
    "docs": [
      {
        … stuff deleted
        "sm_group__members": [
          "John Doe",
          "Peter Parker",
          "Bruce Wayne",
          "Clark Kent",
          "Diana Prince",
          "Arthur Curry",
          "Jack Napier",
          "James Howlett"
        ],
       … stuff deleted
      }
    ]
  }
}

Evidence 3: GraphQL Explorer results

  • Actual Results: group__members is just a single string with just one of the names.
  • Expected Results: group_members is an array of name strings.
{
  "data": {
    "searchAPISearch": {
      "count": 1,
      "facets": [
        {
          "name": "group__type",
          "values": [
            {
              "count": 1,
              "filter": "!"
            }
          ]
        },
        {
          "name": "group__members",
          "values": [
            {
              "count": 1,
              "filter": "Arthur Curry"
            },
            {
              "count": 1,
              "filter": "Bruce Wayne"
            },
            {
              "count": 1,
              "filter": "Clark Kent"
            },
            {
              "count": 1,
              "filter": "Diana Prince"
            },
            {
              "count": 1,
              "filter": "Jack Napier"
            },
            {
              "count": 1,
              "filter": "James Howlett"
            },
            {
              "count": 1,
              "filter": "John Doe"
            },
            {
              "count": 1,
              "filter": "Peter Parker"
            }
          ]
        }
      ],
      "documents": [
        {
          … stuff deleted
          "group__members": "John Doe",
          … stuff deleted
        }
      ]
    }
  }
}
@carolpettirossi
Copy link
Collaborator

Hi @kwiechmann,

Thanks for the very explained problem and all the evidence. It helped me to understand what you are facing.

I've added support for multivalue fields defined via search API processor.

Can you please help me validating this?
You should be able to test by applying this patch: https://patch-diff.githubusercontent.com/raw/drupal-graphql/graphql-search-api/pull/46.patch

Also, you will also need to update the $definition adding the is_list to it:

    $definition = array(
     'label' => $this->t('Group Members'),
     'description' => $this->t('Custom field for storing all members that belong to this group.'),
     'type' => 'string',
     'is_list' => TRUE, // <= added this
     'processor_id' => $this->getPluginId(),
   );

@carolpettirossi carolpettirossi added bug Something isn't working needs review/QA Waiting for someone to validate labels Mar 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs review/QA Waiting for someone to validate
Projects
None yet
2 participants