You are here

public function SearchApiSolrLocationTest::testBackend in Search API Solr 4.x

Same name and namespace in other branches
  1. 8.3 tests/src/Kernel/SearchApiSolrLocationTest.php \Drupal\Tests\search_api_solr\Kernel\SearchApiSolrLocationTest::testBackend()
  2. 8 tests/src/Kernel/SearchApiSolrLocationTest.php \Drupal\Tests\search_api_solr\Kernel\SearchApiSolrLocationTest::testBackend()
  3. 8.2 tests/src/Kernel/SearchApiSolrLocationTest.php \Drupal\Tests\search_api_solr\Kernel\SearchApiSolrLocationTest::testBackend()

Tests location searches and distance facets.

File

tests/src/Kernel/SearchApiSolrLocationTest.php, line 116

Class

SearchApiSolrLocationTest
Tests location searches and distance facets using the Solr search backend.

Namespace

Drupal\Tests\search_api_solr\Kernel

Code

public function testBackend() {

  // Regression test.
  // @see https://www.drupal.org/project/search_api_solr/issues/2921774
  $query = $this
    ->buildSearch(NULL, [], NULL, TRUE);
  $query
    ->addCondition('location', NULL, '<>');
  $result = $query
    ->execute();
  $this
    ->assertResults([
    1,
    2,
    3,
  ], $result, 'Search for all documents having a location');

  // Search 500km from Antwerp.
  $location_options = [
    [
      'field' => 'location',
      'lat' => '51.260197',
      'lon' => '4.402771',
      'radius' => '500',
    ],
  ];

  /** @var \Drupal\search_api\Query\ResultSet $result */
  $query = $this
    ->buildSearch(NULL, [], NULL, FALSE)
    ->sort('location__distance');
  $query
    ->setOption('search_api_location', $location_options);
  $result = $query
    ->execute();
  $this
    ->assertResults([
    3,
    1,
  ], $result, 'Search for 500km from Antwerp ordered by distance');

  /** @var \Drupal\search_api\Item\Item $item */
  $item = $result
    ->getResultItems()['entity:entity_test_mulrev_changed/3:en'];
  $distance = $item
    ->getField('location__distance')
    ->getValues()[0];

  // We get different precisions from Solr 6 and 7. Therefore we treat the
  // decimal as string and compare the first 9 characters.
  $this
    ->assertEquals('42.526337', substr($distance, 0, 9), 'The distance is correctly returned');

  // Search between 100km and 6000km from Antwerp.
  $location_options = [
    [
      'field' => 'location',
      'lat' => '51.260197',
      'lon' => '4.402771',
    ],
  ];
  $query = $this
    ->buildSearch(NULL, [], NULL, FALSE)
    ->addCondition('location', [
    '100',
    '6000',
  ], 'BETWEEN')
    ->sort('location__distance', 'DESC');
  $query
    ->setOption('search_api_location', $location_options);
  $result = $query
    ->execute();
  $this
    ->assertResults([
    2,
    1,
  ], $result, 'Search between 100 and 6000km from Antwerp ordered by distance descending');
  $facets_options['location__distance'] = [
    'field' => 'location__distance',
    'limit' => 10,
    'min_count' => 1,
    'missing' => TRUE,
  ];

  // Search 1000km from Antwerp.
  $location_options = [
    [
      'field' => 'location',
      'lat' => '51.260197',
      'lon' => '4.402771',
      'radius' => '1000',
    ],
  ];
  $query = $this
    ->buildSearch(NULL, [], NULL, FALSE)
    ->sort('location__distance');
  $query
    ->setOption('search_api_location', $location_options);
  $query
    ->setOption('search_api_facets', $facets_options);
  $result = $query
    ->execute();
  $facets = $result
    ->getExtraData('search_api_facets', [])['location__distance'];
  $expected = [
    [
      'filter' => '[0 199]',
      'count' => 1,
    ],
    [
      'filter' => '[200 399]',
      'count' => 1,
    ],
  ];
  $this
    ->assertEquals($expected, $facets, 'The correct location facets are returned');
  $facets_options['location__distance'] = [
    'field' => 'location__distance',
    'limit' => 3,
    'min_count' => 1,
    'missing' => TRUE,
  ];

  // Search between 100km and 1000km from Antwerp.
  $location_options = [
    [
      'field' => 'location',
      'lat' => '51.260197',
      'lon' => '4.402771',
      'radius' => '1000',
    ],
  ];
  $query = $this
    ->buildSearch(NULL, [], NULL, FALSE)
    ->addCondition('location', [
    '100',
    '1000',
  ], 'BETWEEN')
    ->sort('location__distance');
  $query
    ->setOption('search_api_location', $location_options);
  $query
    ->setOption('search_api_facets', $facets_options);
  $result = $query
    ->execute();
  $facets = $result
    ->getExtraData('search_api_facets', [])['location__distance'];
  $expected = [
    [
      'filter' => '[100 399]',
      'count' => 1,
    ],
  ];
  $this
    ->assertEquals($expected, $facets, 'The correct location facets are returned');

  // Tests the RPT data type of SearchApiSolrBackend.
  $query = $this
    ->buildSearch(NULL, [], NULL, FALSE);
  $options =& $query
    ->getOptions();
  $options['search_api_facets']['rpt'] = [
    'field' => 'rpt',
    'limit' => 3,
    'operator' => 'and',
    'min_count' => 1,
    'missing' => FALSE,
  ];
  $options['search_api_rpt']['rpt'] = [
    'field' => 'rpt',
    'geom' => '["-180 -90" TO "180 90"]',
    'gridLevel' => '2',
    'maxCells' => '35554432',
    'distErrPct' => '',
    'distErr' => '',
    'format' => 'ints2D',
  ];
  $result = $query
    ->execute();

  // @codingStandardsIgnoreLine
  $heatmap = [
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      1,
      1,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
    ],
    NULL,
    [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
    ],
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
  ];
  $filter = [];
  if (version_compare($this
    ->getSolrVersion(), '7.5', '>=')) {
    $filter = [
      "gridLevel" => 2,
      "columns" => 32,
      "rows" => 32,
      "minX" => -180.0,
      "maxX" => 180.0,
      "minY" => -90.0,
      "maxY" => 90.0,
      "counts_ints2D" => $heatmap,
    ];
  }
  else {
    $filter = [
      "gridLevel",
      2,
      "columns",
      32,
      "rows",
      32,
      "minX",
      -180.0,
      "maxX",
      180.0,
      "minY",
      -90.0,
      "maxY",
      90.0,
      "counts_ints2D",
      $heatmap,
    ];
  }
  $expected = [
    [
      'filter' => $filter,
      'count' => 3,
    ],
  ];
  $facets = $result
    ->getExtraData('search_api_facets', [])['rpt'];
  $this
    ->assertEquals($expected, $facets, 'The correct location facets are returned');
  $query = $this
    ->buildSearch(NULL, [], NULL, FALSE);
  $options =& $query
    ->getOptions();
  $options['search_api_facets']['rpt'] = [
    'field' => 'rpt',
    'limit' => 4,
    'operator' => 'or',
    'min_count' => 1,
    'missing' => FALSE,
  ];
  $options['search_api_rpt']['rpt'] = [
    'field' => 'rpt',
    'geom' => '["-60 -85" TO "130 70"]',
    'gridLevel' => '2',
    'maxCells' => '35554432',
    'distErrPct' => '',
    'distErr' => '',
    'format' => 'ints2D',
  ];
  $result = $query
    ->execute();

  // @codingStandardsIgnoreLine
  $heatmap = [
    NULL,
    NULL,
    NULL,
    [
      0,
      0,
      0,
      0,
      0,
      1,
      1,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
    ],
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
  ];
  $filter = [];
  if (version_compare($this
    ->getSolrVersion(), '7.5', '>=')) {
    $filter = [
      "gridLevel" => 2,
      "columns" => 18,
      "rows" => 29,
      "minX" => -67.5,
      "maxX" => 135.0,
      "minY" => -90.0,
      "maxY" => 73.125,
      "counts_ints2D" => $heatmap,
    ];
  }
  else {
    $filter = [
      "gridLevel",
      2,
      "columns",
      18,
      "rows",
      29,
      "minX",
      -67.5,
      "maxX",
      135.0,
      "minY",
      -90.0,
      "maxY",
      73.125,
      "counts_ints2D",
      $heatmap,
    ];
  }
  $expected = [
    [
      'filter' => $filter,
      'count' => 2,
    ],
  ];
  $facets = $result
    ->getExtraData('search_api_facets', [])['rpt'];
  $this
    ->assertEquals($expected, $facets, 'The correct location facets are returned');

  // Test boundary filtering.
  $query = $this
    ->buildSearch()
    ->addCondition('location', [
    '38,-75',
    '42,-70',
  ], 'BETWEEN');
  $result = $query
    ->execute();
  $this
    ->assertResults([
    2,
  ], $result, 'Search for NYC by boundary and NYC only');
  $query = $this
    ->buildSearch()
    ->addCondition('location', [
    '38,-75',
    '42,-70',
  ], 'NOT BETWEEN');
  $result = $query
    ->execute();
  $this
    ->assertResults([
    1,
    3,
  ], $result, 'Search for outside NYC by boundary');
}