SlideShare a Scribd company logo
Apache Solr
Search Mastery
Peter Wolanin and Robert Douglass
                               25. aug 13:30
                               Trellon
We	
  hope	
  you	
  will	
  leave	
  having	
  
                learned	
  about:

•   What	
  is	
  Solr	
  and	
  how	
  do	
  you	
  run	
  it	
  locally
•   Ge9ng	
  Drupal	
  data	
  into	
  Solr
•   Changes	
  in	
  Drupal	
  7
•   Field	
  API	
  integraAon
•   Searching	
  Solr	
  from	
  Drupal
•   Modifying	
  what’s	
  searched	
  and	
  the	
  results
•   Theming	
  search	
  results
Drupal	
  Interacts	
  with	
  Solr	
  via	
  HTTP
•    Drupal	
  sends	
  data	
  to	
  Solr	
  as	
  XML	
  documents
•    Solr	
  accepts	
  documents	
  POSTed	
  to	
  /update
•    A	
  different	
  XML	
  can	
  be	
  POSTed	
  to	
  delete
•    Searching,	
  etc	
  are	
  GET	
  requests
•    If	
  something	
  is	
  not	
  working	
  as	
  expected,	
  you	
  
           can	
  try	
  searching	
  directly	
  in	
  Solr	
  via	
  URL
•    Solr	
  also	
  includes	
  admin	
  and	
  analysis	
  interfaces	
  
           (you	
  need	
  to	
  lock	
  this	
  down	
  for	
  producAon).
Run	
  Solr	
  Using	
  the	
  Example	
  Dir


                     Replace the schema.xml and
                     solrconfig.xml with the ones from
                     the Drupal module



                         Invoke the start.jar:

                         java -jar start.jar
Apache Solr Search Mastery
Schema:	
  Defines	
  Types	
  &	
  Fields
<?xml version="1.0" encoding="UTF-8" ?>
<schema name="drupal-0.9.5" version="1.2">
  <types>
    ...
 </types>
 <fields>
<!-- The document id is derived from a site-spcific key (hash) and the node ID like:
     $document->id = $hash . '/node/' . $node->nid; -->
   <field name="id" type="string" indexed="true" stored="true" required="true" />
<!-- These are the fields that correspond to a Drupal node. -->
   <field name="site" type="string" indexed="true" stored="true"/>
   <field name="hash" type="string" indexed="true" stored="true"/>
   <field name="url" type="string" indexed="true" stored="true"/>
   <field name="title" type="text" indexed="true" stored="true" termVectors="true"
           omitNorms="true"/>
   <field name="sort_title" type="sortString" indexed="true" stored="false"/>
   <field name="body" type="text" indexed="true" stored="true" termVectors="true"/>
   <field name="teaser" type="text" indexed="false" stored="true"/>
   ...
 </fields>
 <uniqueKey>id</uniqueKey>
 <!-- field for the QueryParser to use when an explicit fieldname is absent -->
 <defaultSearchField>body</defaultSearchField>

 <!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
 <solrQueryParser defaultOperator="AND"/>
</schema>
Schema:	
  Defines	
  Types	
  &	
  Fields

<field name="id" type="string" indexed="true"
 stored="true" required="true" />
<!-- These are the fields that correspond to a
Drupal node. -->
<field name="site" type="string" indexed="true"
 stored="true"/>
<field name="hash" type="string" indexed="true"
 stored="true"/>
Dynamic	
  Fields	
  Provide	
  Flexibility
  <!-- Dynamic field definitions will be used if the name matches any of the patterns.
       The glob-like pattern in the name attribute must have "*" only at the start or the end.
       Longer patterns will be matched first.   -->

  <dynamicField   name="is_*" type="integer" indexed="true"     stored="true" multiValued="false"/>
  <dynamicField   name="im_*" type="integer" indexed="true"     stored="true" multiValued="true"/>
...
  <dynamicField   name="ss_*" type="string"    indexed="true"   stored="true" multiValued="false"/>
  <dynamicField   name="ts_*" type="text"      indexed="true"   stored="true" multiValued="false"
                  termVectors="true"/>
  <dynamicField   name="ds_*" type="date"  indexed="true" stored="true" multiValued="false"/>
  <dynamicField   name="dm_*" type="date"  indexed="true" stored="true" multiValued="true"/>
  <dynamicField   name="tds_*" type="tdate"indexed="true" stored="true" multiValued="false"/>
  <dynamicField   name="tdm_*" type="tdate"indexed="true" stored="true" multiValued="true"/>
  <dynamicField   name="bm_*" type="boolean"
                                           indexed="true" stored="true" multiValued="true"/>
  <dynamicField   name="bs_*" type="boolean"
                                           indexed="true" stored="true" multiValued="false"/>
...
  <!-- Sortable version of the dynamic string field -->
  <dynamicField name="sort_ss_*" type="sortString" indexed="true" stored="false"/>
  <copyField source="ss_*" dest="sort_ss_*"/>
 <!-- A random sort field -->
  <dynamicField name="random_*" type="rand" indexed="true" stored="true"/>
  <!-- This field is used to store node access records, as opposed to CCK field data -->
  <dynamicField name="nodeaccess*" type="integer" indexed="true" stored="false"
                multiValued="true"/>

  <dynamicField name="*" type="ignored" multiValued="true" />
Dynamic	
  Fields	
  Provide	
  Flexibility
<!-- Dynamic field definitions will be used
if the name matches any of the patterns.
The glob-like pattern in the name attribute must
have "*" only at the start or the end.
Longer patterns will be matched first.   -->

<dynamicField name="is_*" type="integer"
 indexed="true" stored="true"
 multiValued="false"/>
<dynamicField name="im_*" type="integer"
 indexed="true" stored="true"
 multiValued="true"/>
Dynamic	
  Fields	
  Provide	
  Flexibility
  <!-- Dynamic field definitions will be used if the name matches any of the patterns.
       The glob-like pattern in the name attribute must have "*" only at the start or the end.
       Longer patterns will be matched first.   -->

  <dynamicField   name="is_*" type="integer" indexed="true"     stored="true" multiValued="false"/>
  <dynamicField   name="im_*" type="integer" indexed="true"     stored="true" multiValued="true"/>
...
  <dynamicField   name="ss_*" type="string"    indexed="true"   stored="true" multiValued="false"/>
  <dynamicField   name="ts_*" type="text"      indexed="true"   stored="true" multiValued="false"
                  termVectors="true"/>
  <dynamicField   name="ds_*" type="date"  indexed="true" stored="true" multiValued="false"/>
  <dynamicField   name="dm_*" type="date"  indexed="true" stored="true" multiValued="true"/>
  <dynamicField   name="tds_*" type="tdate"indexed="true" stored="true" multiValued="false"/>
  <dynamicField   name="tdm_*" type="tdate"indexed="true" stored="true" multiValued="true"/>
  <dynamicField   name="bm_*" type="boolean"
                                           indexed="true" stored="true" multiValued="true"/>
  <dynamicField   name="bs_*" type="boolean"
                                           indexed="true" stored="true" multiValued="false"/>
...
  <!-- Sortable version of the dynamic string field -->
  <dynamicField name="sort_ss_*" type="sortString" indexed="true" stored="false"/>
  <copyField source="ss_*" dest="sort_ss_*"/>
 <!-- A random sort field -->
  <dynamicField name="random_*" type="rand" indexed="true" stored="true"/>
  <!-- This field is used to store node access records, as opposed to CCK field data -->
  <dynamicField name="nodeaccess*" type="integer" indexed="true" stored="false"
                multiValued="true"/>

  <dynamicField name="*" type="ignored" multiValued="true" />
Dynamic	
  Fields	
  Provide	
  Flexibility
<!-- Sortable version of the dynamic
     string field -->
<dynamicField name="sort_ss_*" type="sortString"
 indexed="true" stored="false"/>
<copyField source="ss_*" dest="sort_ss_*"/>

<!-- This field is used to store node access
 records, as opposed to CCK field data -->
<dynamicField name="nodeaccess*"
 type="integer" indexed="true" stored="false"
 multiValued="true"/>

<dynamicField name="*" type="ignored"
 multiValued="true" />
The $query object
Use the factory method to get an object for
building your queries:

$query = apachesolr_drupal_query(
   $keys = '',
   $filters = '',
   $solrsort = '',
   $base_path = '',
   $solr = NULL
);
The actual class that is returned is
determined by a Drupal variable:



variable_get('apachesolr_query_class',
array('apachesolr', 'Solr_Base_Query'));
interface Drupal_Solr_Query_Interface {
  get_filters($name);

    has_filter($field, $value);

    add_filter($field, $value, $exclude);

    remove_filter($field, $value);

    ...
}
interface Drupal_Solr_Query_Interface {
  ...

    get_keys();

    set_keys($keys);

    remove_keys();

    ...
}
interface Drupal_Solr_Query_Interface {
  ...

    get_path();

    get_url_queryvalues();

    get_query_basic();

    ...
}
interface Drupal_Solr_Query_Interface {
  ...

    get_available_sorts();

    set_available_sort($field, $sort);

    get_solrsort();

    set_solrsort($field, $direction);
    ...
}
interface Drupal_Solr_Query_Interface {
  ...

    add_subquery(
     Drupal_Solr_Query_Interface $query);

    remove_subquery(
     Drupal_Solr_Query_Interface $query);

    remove_subqueries();
    ...
}
interface Drupal_Solr_Query_Interface {
  ...

    // Passes to the $solr object which
    // executes the search.
    search($keys = NULL);

}
The $solr object
Use the factory method to get an object for
sending requests to Solr:



$solr =
 apachesolr_get_solr($host, $port, $path);
The actual class that is returned is
determined by a Drupal variable:



variable_get('apachesolr_service_class',
   array('apachesolr',
         'Drupal_Apache_Solr_Service.php',
         'Drupal_Apache_Solr_Service')
);
This allows you to customize the way
search works by providing a different solr
service class than the standard.


variable_set('apachesolr_service_class',
  array('acquia_search',
         'Acquia_Search_Service.php',
         'Acquia_Search_Service')
);
http://code.google.com/p/solr-php-client/

class Apache_Solr_Service {

    addDocument(
        Apache_Solr_Document $document);
    addDocuments($documents);
    deleteById($id);
    deleteByQuery($rawQuery);
    ...
}
http://code.google.com/p/solr-php-client/

class Apache_Solr_Service {
 ...

    ping();
    commit();
    optimize();

    ...
}
http://code.google.com/p/solr-php-client/

class Apache_Solr_Service {

    // Builds a GET request.
    search();

}
class Drupal_Apache_Solr_Service
 extends Apache_Solr_Service {

    getLuke();
    getFields();
    getStatsSummary();

    ...
}
class Drupal_Apache_Solr_Service
 extends Apache_Solr_Service {

    // Takes control of the request sending
    // and headers - Drupal idiomatic.
    _makeHttpRequest();

}
The $document object
http://code.google.com/p/solr-php-client/

class Apache_Solr_Document {

    addField($key, $value, $boost);
    setMultiValue($key, $value, $boost);

}
Drupal	
  7	
  Changes	
  

    $query, $params                      $query->params

    $solr->search()                      $query->search()


•   Taxonomy	
  on	
  a	
  node	
  is	
  now	
  a	
  term	
  reference	
  field	
  
      (works	
  as	
  part	
  of	
  the	
  Field	
  API	
  integraAon).
•   Fixes	
  to	
  core	
  search	
  module	
  APIs	
  mean	
  that	
  some	
  
      hacks	
  are	
  gone:	
  e.g.	
  no,	
  hook_menu_alter;	
  we	
  
      can	
  set	
  apachesolr	
  as	
  the	
  default	
  via	
  search	
  UI.
You	
  Can	
  Add	
  Any	
  Data	
  to	
  the	
  Index
hook_apachesolr_update_index(&$document,
$node, $namespace)

•    Used	
  to	
  add	
  more	
  data	
  to	
  a	
  document	
  before	
  
       it’s	
  sent	
  to	
  Solr.
•    Can	
  also	
  be	
  used	
  to	
  alter	
  or	
  replace	
  data	
  added	
  
       by	
  apachesolr	
  or	
  another	
  module.
•    This	
  is	
  it!	
  (it	
  works	
  like	
  an	
  _alter	
  hook).
Image	
  Data	
  Using	
  Dynamic	
  Fields
/**
  * Implementation of hook_apachesolr_update_index().
  */
function apachesolr_image_apachesolr_update_index(&$document, $node, $namespace) {
   if ($node->type == 'image' && $document->entity == 'node') {
     $areas = array();
     $sizes = image_get_derivative_sizes($node->images['_original']);
     foreach ($sizes as $name => $info) {
       $areas[$name] = $info['width'] * $info['height'];
     }
     asort($areas);
     $image_path = FALSE;
     foreach ($areas as $preset => $size) {
       $image_path = $node->images[$preset];
       break;
     }
     if ($image_path) {
       $document->ss_image_relative = $image_path;
       // Support multi-site too.
       $document->ss_image_absolute = file_create_url($image_path);
     }
   }
}

/**
  * Implementation of hook_apachesolr_modify_query().
  */
function apachesolr_image_apachesolr_modify_query($query, $caller) {
   // Also retrieve image thumbnail links.
   $query->params['fl'] .= ',ss_image_relative';
}
Image	
  Data	
  Using	
  Dynamic	
  Fields
 if ($image_path) {
   $document->ss_image_relative = $image_path;
 }

/**
  * Implement hook_apachesolr_modify_query().
  */
function
apachesolr_image_apachesolr_modify_query(
$query, $caller) {
   // Also retrieve image thumbnail links.
   $query->params['fl'] .= ',ss_image_relative';
}
UI	
  to	
  Exclude	
  Whole	
  Content	
  Types
•   ?q=admin/config/search/apachesolr/content-­‐bias
Control	
  Indexing	
  More	
  Precisely	
  
hook_apachesolr_node_exclude($node, $namespace)

in_array($node->type, variable_get(
'apachesolr_exclude_comments_types', array()))

hook_node_update_index($node)

•   hook_node_update_index	
  output	
  added	
  to	
  body.
•   We	
  can	
  create	
  mulAple	
  documents	
  from	
  one	
  node	
  
      (e.g.	
  document	
  per	
  comment).
hook_apachesolr_document_handlers($type,
$namespace)
Field	
  API	
  IntegraAon
•   Most	
  of	
  the	
  Field	
  API	
  integraAon	
  follows	
  
       directly	
  from	
  the	
  6.x-­‐2.x	
  CCK	
  integraAon.
•   In	
  Drupal	
  7,	
  we	
  match	
  field	
  types,	
  rather	
  than	
  
       looking	
  at	
  the	
  widget.
•   By	
  default,	
  the	
  data	
  will	
  be	
  indexed	
  to	
  Solr	
  as	
  
       mulA-­‐valued,	
  and	
  named	
  combining	
  the	
  field	
  
       module	
  and	
  name	
  sm_$module_$fieldname
Typically	
  need	
  4	
  things:
•   What	
  field	
  types	
  (or	
  field	
  instances)	
  to	
  look	
  
         for	
  during	
  indexing.
•   The	
  data	
  type	
  to	
  use	
  in	
  the	
  index	
  
         (index_type)
•   A	
  funcAon	
  for	
  extracAng	
  the	
  data	
  from	
  the	
  
         field	
  while	
  indexing	
  (indexing_callback).
•   A	
  funcAon	
  for	
  displaying	
  the	
  data	
  from	
  the	
  
         field	
  during	
  searches	
  (display_callback).
Field	
  API	
  IntegraAon
hook_apachesolr_field_mappings_alter
(&$mappings)

$mappings['list_text'] = array(
   'display_callback' =>
     'apachesolr_fields_list_display_callback',
   'indexing_callback' =>
     'apachesolr_fields_list_indexing_callback',
   'index_type' =>
     'string',
);
Apache Solr Search Mastery
Apache Solr Search Mastery
Analysis of an apachesolr search request
   	 
           	 
                search_view()



        $response = $query->search(...)
$results = apachesolr_search_process_response
          ($response,$final_query)


   theme('search_results', $results, ...)
Analysis of an apachesolr search request
   	 
           	 
                search_view()



        $response = $query->search(...)
$results = apachesolr_search_process_response
          ($response,$final_query)


   theme('search_results', $results, ...)
hook_menu: defines custom search paths

/arts

/arts/undergraduate

/search/apachesolr_search/?
filters=type%3Acatalog%20
ss_faculty%3AAR%20sm_level
%3AUndergraduate
hook_menu: defines custom search paths

/arts

/arts/undergraduate

/arts/undergraduate/courses
hook_menu: defines custom search paths




// Implements hook_menu().
function mcgill_menu() {
  $items['arts/undergraduate/courses'] = array(
    'page callback' => 'mcgill_courses_search',
    'access arguments' => array('search content'),
    'type' => MENU_CALLBACK,
  );
   return $items;
}
Analysis of an apachesolr search request
   	 
           	 
                search_view()



        $response = $query->search(...)
$results = apachesolr_search_process_response
          ($response,$final_query)


   theme('search_results', $results, ...)
hook_menu_alter: changes the page callback
hook_menu_alter: changes the page callback
hook_menu_alter: changes the page callback
hook_menu_alter: changes the page callback
hook_menu_alter: changes the page callback




// Implements hook_menu_alter().
function mcgill_menu_alter(&$items) {
  if (isset($items['search/apachesolr_search/%menu_tail'])) {
    $items['search']['page callback'] = 'mcgill_page';
    $items['search/apachesolr_search/%menu_tail']['page callback'] = 'mcgill_page';
  }
}
Analysis of an apachesolr search request
   	 
           	 
                search_view()



        $response = $query->search(...)
$results = apachesolr_search_process_response
          ($response,$final_query)


   theme('search_results', $results, ...)
An example Solr request
Analysis of an apachesolr search request
  	 
          	 
               search_view()



       $response = $query->search(...)
$results = apachesolr_search_process_response
          ($response,$final_query)


   theme('search_results', $results, ...)
hook_apachesolr_prepare_query($query)
Analysis of an apachesolr search request
        	 
                	 
                     search_view()



             $response = $query->search(...)
$results = apachesolr_process_response($response, ...)
     $results = apachesolr_search_process_response
               ($response,$final_query)


       theme('search_results', $results, ...)
hook_apachesolr_prepare/modify_query($query)




// Run hook_apachesolr_prepare_query($query).

// Cache the built query.
$current_query = apachesolr_current_query($query);

// Run hook_apachesolr_modify_query($query).
hook_apachesolr_prepare/modify_query($query)
hook_apachesolr_prepare/modify_query($query)
hook_apachesolr_prepare_query($query):
    set a default Solr sort parameter
hook_apachesolr_prepare_query($query):
            set a default Solr sort parameter



$query->set_available_sort('sort_ss_course_code', array(
  'title' => t('Course code'),
  'default' => 'asc',
));
$query->remove_available_sort('created');
$query->remove_available_sort('sort_name');
$query->remove_available_sort('type');
hook_apachesolr_prepare_query($query):
            set a default Solr sort parameter


if (!isset($_GET['solrsort'])) {
  if ($query->get_keys()) {
    $query->set_solrsort('score', 'asc');
  }
  else {
    $query->set_solrsort('sort_ss_course_code', 'asc');
  }
}
hook_apachesolr_prepare/modify_query($query)
Should I use hook_apachesolr_prepare_query
      or hook_apachesolr_modify_query?




/arts/undergraduate/courses
Should I use hook_apachesolr_prepare_query
    or hook_apachesolr_modify_query?
Should I use hook_apachesolr_prepare_query
    or hook_apachesolr_modify_query?
Should I use hook_apachesolr_prepare_query
    or hook_apachesolr_modify_query?
Should I use hook_apachesolr_prepare_query
    or hook_apachesolr_modify_query?
Should I use hook_apachesolr_prepare_query
    or hook_apachesolr_modify_query?
hook_apachesolr_modify_query($query):
          set default Solr fq parameters


// Add filters for FACULTY/LEVEL/courses paths.
if ($facet = get_faculty_from_path()) {
  $query->add_filter('ss_faculty', $facet);
}
if ($facet = get_level_from_path()) {
  $query->add_filter('sm_level', $facet);
}
hook_apachesolr_prepare/modify_query($query)
hook_apachesolr_prepare/modify_query($query)
      Set Solr parameters in $query->params




$query->params['fl'] .=
',ss_course_code';

$query->params['facet.limit'] = -1;
Analysis of an apachesolr search request
   	 
           	 
                search_view()



        $response = $query->search(...)
$results = apachesolr_search_process_response
          ($response,$final_query)


   theme('search_results', $results, ...)
Analysis of an apachesolr search request
   	 
           	 
                search_view()



        $response = $query->search(...)
$results = apachesolr_search_process_response
          ($response,$final_query)
                                   	 
   theme('search_results', $results, ...)
theme_apachesolr_search_snippets: sets the snippet
theme_apachesolr_search_snippets: sets the snippet




// Default implementation in apachesolr_search.module.
function theme_apachesolr_search_snippets($document, $snippets) {
  return implode(' ... ', $snippets) . ' ...';
}
theme_apachesolr_search_snippets: sets the snippet
theme_apachesolr_search_snippets: sets the snippet




// Custom implementation in template.php.
function mcgill_apachesolr_search_snippets($document, $snippets) {
  return 'anything you want!';
}
Analysis of an apachesolr search request
   	 
           	 
                search_view()



        $response = $query->search(...)
$results = apachesolr_search_process_response
          ($response,$final_query)
                                   	 
   theme('search_results', $results, ...)
search-result.tpl.php: renders a single search result



<?php print $result['node']->ss_course_code; ?>




If this is user input use check_plain() - Solr can
send you back the same (unsafe) user input you index.
See apachesolr_clean_text() if you want to index text
without tags.
Extra thanks to
     James McKinney
For use of his slides and for ideas.
jpmckinney on drupal.org
http://evolvingweb.ca/
http://cph2010.drupal.org/node/8168

More Related Content

What's hot

Solr Anti - patterns
Solr Anti - patternsSolr Anti - patterns
Solr Anti - patterns
Rafał Kuć
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
Azim Kurt
 
Getting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, AgainGetting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, Again
DrewAPicture
 
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
Donghyeok Kang
 
Hacking Your Way To Better Security
Hacking Your Way To Better SecurityHacking Your Way To Better Security
Hacking Your Way To Better Security
Colin O'Dell
 
Hacking Your Way to Better Security - PHP South Africa 2016
Hacking Your Way to Better Security - PHP South Africa 2016Hacking Your Way to Better Security - PHP South Africa 2016
Hacking Your Way to Better Security - PHP South Africa 2016
Colin O'Dell
 
Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016
Colin O'Dell
 
Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016
Colin O'Dell
 
Solr Anti-Patterns: Presented by Rafał Kuć, Sematext
Solr Anti-Patterns: Presented by Rafał Kuć, SematextSolr Anti-Patterns: Presented by Rafał Kuć, Sematext
Solr Anti-Patterns: Presented by Rafał Kuć, Sematext
Lucidworks
 
supporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered tablesupporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered table
Mahabubur Rahaman
 
Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)
brockboland
 
Views notwithstanding
Views notwithstandingViews notwithstanding
Views notwithstanding
Srikanth Bangalore
 
UITableView Pain Points
UITableView Pain PointsUITableView Pain Points
UITableView Pain Points
Ken Auer
 
Your code sucks, let's fix it - PHP Master Series 2012
Your code sucks, let's fix it - PHP Master Series 2012Your code sucks, let's fix it - PHP Master Series 2012
Your code sucks, let's fix it - PHP Master Series 2012
Rafael Dohms
 
Drupal 8: Forms
Drupal 8: FormsDrupal 8: Forms
Drupal 8: Forms
drubb
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
Fabien Potencier
 
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
Ontico
 
Php (1)
Php (1)Php (1)
Php (1)
pinalsadiwala
 
Mysql query optimization
Mysql query optimizationMysql query optimization
Mysql query optimization
Baohua Cai
 

What's hot (19)

Solr Anti - patterns
Solr Anti - patternsSolr Anti - patterns
Solr Anti - patterns
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
Getting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, AgainGetting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, Again
 
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
 
Hacking Your Way To Better Security
Hacking Your Way To Better SecurityHacking Your Way To Better Security
Hacking Your Way To Better Security
 
Hacking Your Way to Better Security - PHP South Africa 2016
Hacking Your Way to Better Security - PHP South Africa 2016Hacking Your Way to Better Security - PHP South Africa 2016
Hacking Your Way to Better Security - PHP South Africa 2016
 
Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016
 
Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016
 
Solr Anti-Patterns: Presented by Rafał Kuć, Sematext
Solr Anti-Patterns: Presented by Rafał Kuć, SematextSolr Anti-Patterns: Presented by Rafał Kuć, Sematext
Solr Anti-Patterns: Presented by Rafał Kuć, Sematext
 
supporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered tablesupporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered table
 
Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)
 
Views notwithstanding
Views notwithstandingViews notwithstanding
Views notwithstanding
 
UITableView Pain Points
UITableView Pain PointsUITableView Pain Points
UITableView Pain Points
 
Your code sucks, let's fix it - PHP Master Series 2012
Your code sucks, let's fix it - PHP Master Series 2012Your code sucks, let's fix it - PHP Master Series 2012
Your code sucks, let's fix it - PHP Master Series 2012
 
Drupal 8: Forms
Drupal 8: FormsDrupal 8: Forms
Drupal 8: Forms
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
 
Php (1)
Php (1)Php (1)
Php (1)
 
Mysql query optimization
Mysql query optimizationMysql query optimization
Mysql query optimization
 

Viewers also liked

Southern%20Honduras%20Vulnerability%20Assessment%20Report_CLEARED
Southern%20Honduras%20Vulnerability%20Assessment%20Report_CLEAREDSouthern%20Honduras%20Vulnerability%20Assessment%20Report_CLEARED
Southern%20Honduras%20Vulnerability%20Assessment%20Report_CLEARED
Luis Caballero Bonilla
 
Francy lorena mancholacruz_actividad1_2mapac
Francy lorena mancholacruz_actividad1_2mapacFrancy lorena mancholacruz_actividad1_2mapac
Francy lorena mancholacruz_actividad1_2mapac
lorena cruz
 
Plano l11638
Plano l11638Plano l11638
Plano l11638
Dennis Neves
 
Elementary & Auxiliary Strategies Imparting Smartness to a city
Elementary & Auxiliary Strategies Imparting Smartness to a cityElementary & Auxiliary Strategies Imparting Smartness to a city
Elementary & Auxiliary Strategies Imparting Smartness to a city
Antara Nandy
 
From Activiti to camunda fox: The SaaS Scenario
From Activiti to camunda fox: The SaaS ScenarioFrom Activiti to camunda fox: The SaaS Scenario
From Activiti to camunda fox: The SaaS Scenario
Sven Jörges
 
Power point cam
Power point camPower point cam
Power point cam
MARIA SECADES CUESTA
 
Sprinklr vs Salesforce
Sprinklr vs SalesforceSprinklr vs Salesforce
Sprinklr vs Salesforce
Empire Selling
 
WE HATE CUSTOMERS
WE HATE CUSTOMERSWE HATE CUSTOMERS
WE HATE CUSTOMERS
Laimonas Burneckis
 
Real-Life-BPM mit Java EE: Ein Erfahrungsbericht
Real-Life-BPM mit Java EE: Ein ErfahrungsberichtReal-Life-BPM mit Java EE: Ein Erfahrungsbericht
Real-Life-BPM mit Java EE: Ein Erfahrungsbericht
Sven Jörges
 
Gestión y control de calidad
Gestión y control de calidadGestión y control de calidad
Gestión y control de calidad
Raúl Cordova
 
Activiti: a developer-friendly process engine
Activiti: a developer-friendly process engineActiviti: a developer-friendly process engine
Activiti: a developer-friendly process engine
Travis Carlson
 
Επαναληπτικό φύλλο εργασίας,, β γυμν Αρχαία, ενότ 1-5
Επαναληπτικό φύλλο εργασίας,, β γυμν Αρχαία, ενότ 1-5Επαναληπτικό φύλλο εργασίας,, β γυμν Αρχαία, ενότ 1-5
Επαναληπτικό φύλλο εργασίας,, β γυμν Αρχαία, ενότ 1-5
chavalesnick
 
Φύλλο εργασίας αρχαια Α΄ γυμν 11 ενοτ
Φύλλο εργασίας αρχαια Α΄ γυμν 11 ενοτΦύλλο εργασίας αρχαια Α΄ γυμν 11 ενοτ
Φύλλο εργασίας αρχαια Α΄ γυμν 11 ενοτ
chavalesnick
 

Viewers also liked (13)

Southern%20Honduras%20Vulnerability%20Assessment%20Report_CLEARED
Southern%20Honduras%20Vulnerability%20Assessment%20Report_CLEAREDSouthern%20Honduras%20Vulnerability%20Assessment%20Report_CLEARED
Southern%20Honduras%20Vulnerability%20Assessment%20Report_CLEARED
 
Francy lorena mancholacruz_actividad1_2mapac
Francy lorena mancholacruz_actividad1_2mapacFrancy lorena mancholacruz_actividad1_2mapac
Francy lorena mancholacruz_actividad1_2mapac
 
Plano l11638
Plano l11638Plano l11638
Plano l11638
 
Elementary & Auxiliary Strategies Imparting Smartness to a city
Elementary & Auxiliary Strategies Imparting Smartness to a cityElementary & Auxiliary Strategies Imparting Smartness to a city
Elementary & Auxiliary Strategies Imparting Smartness to a city
 
From Activiti to camunda fox: The SaaS Scenario
From Activiti to camunda fox: The SaaS ScenarioFrom Activiti to camunda fox: The SaaS Scenario
From Activiti to camunda fox: The SaaS Scenario
 
Power point cam
Power point camPower point cam
Power point cam
 
Sprinklr vs Salesforce
Sprinklr vs SalesforceSprinklr vs Salesforce
Sprinklr vs Salesforce
 
WE HATE CUSTOMERS
WE HATE CUSTOMERSWE HATE CUSTOMERS
WE HATE CUSTOMERS
 
Real-Life-BPM mit Java EE: Ein Erfahrungsbericht
Real-Life-BPM mit Java EE: Ein ErfahrungsberichtReal-Life-BPM mit Java EE: Ein Erfahrungsbericht
Real-Life-BPM mit Java EE: Ein Erfahrungsbericht
 
Gestión y control de calidad
Gestión y control de calidadGestión y control de calidad
Gestión y control de calidad
 
Activiti: a developer-friendly process engine
Activiti: a developer-friendly process engineActiviti: a developer-friendly process engine
Activiti: a developer-friendly process engine
 
Επαναληπτικό φύλλο εργασίας,, β γυμν Αρχαία, ενότ 1-5
Επαναληπτικό φύλλο εργασίας,, β γυμν Αρχαία, ενότ 1-5Επαναληπτικό φύλλο εργασίας,, β γυμν Αρχαία, ενότ 1-5
Επαναληπτικό φύλλο εργασίας,, β γυμν Αρχαία, ενότ 1-5
 
Φύλλο εργασίας αρχαια Α΄ γυμν 11 ενοτ
Φύλλο εργασίας αρχαια Α΄ γυμν 11 ενοτΦύλλο εργασίας αρχαια Α΄ γυμν 11 ενοτ
Φύλλο εργασίας αρχαια Α΄ γυμν 11 ενοτ
 

Similar to Apache Solr Search Mastery

Eric Redmond – Distributed Search on Riak 2.0 - NoSQL matters Barcelona 2014
Eric Redmond – Distributed Search on Riak 2.0 - NoSQL matters Barcelona 2014Eric Redmond – Distributed Search on Riak 2.0 - NoSQL matters Barcelona 2014
Eric Redmond – Distributed Search on Riak 2.0 - NoSQL matters Barcelona 2014
NoSQLmatters
 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
Nicolas Leroy
 
Cassandra summit
Cassandra summitCassandra summit
Cassandra summit
mattstump
 
dcs plus Catalogue 2015
dcs plus Catalogue 2015dcs plus Catalogue 2015
dcs plus Catalogue 2015
dcs plus
 
Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
SPTechCon
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
elliando dias
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngine
MichaelRog
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
Nate Abele
 
Broadleaf Presents Thymeleaf
Broadleaf Presents ThymeleafBroadleaf Presents Thymeleaf
Broadleaf Presents Thymeleaf
Broadleaf Commerce
 
Php
PhpPhp
Solr integration in Magento Enterprise
Solr integration in Magento EnterpriseSolr integration in Magento Enterprise
Solr integration in Magento Enterprise
Tobias Zander
 
Drupal Development (Part 2)
Drupal Development (Part 2)Drupal Development (Part 2)
Drupal Development (Part 2)
Jeff Eaton
 
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
camp_drupal_ua
 
第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource
Kaz Watanabe
 
Solr Anti Patterns
Solr Anti PatternsSolr Anti Patterns
Solr Anti Patterns
Sematext Group, Inc.
 
21. CodeIgniter search
21. CodeIgniter search21. CodeIgniter search
21. CodeIgniter search
Razvan Raducanu, PhD
 
Elasticsearch and Symfony Integration - Debarko De
Elasticsearch and Symfony Integration - Debarko DeElasticsearch and Symfony Integration - Debarko De
Elasticsearch and Symfony Integration - Debarko De
Debarko De
 
DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7
chuvainc
 
Why Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary ThingWhy Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary Thing
Chris Reynolds
 

Similar to Apache Solr Search Mastery (20)

Eric Redmond – Distributed Search on Riak 2.0 - NoSQL matters Barcelona 2014
Eric Redmond – Distributed Search on Riak 2.0 - NoSQL matters Barcelona 2014Eric Redmond – Distributed Search on Riak 2.0 - NoSQL matters Barcelona 2014
Eric Redmond – Distributed Search on Riak 2.0 - NoSQL matters Barcelona 2014
 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
 
Cassandra summit
Cassandra summitCassandra summit
Cassandra summit
 
dcs plus Catalogue 2015
dcs plus Catalogue 2015dcs plus Catalogue 2015
dcs plus Catalogue 2015
 
Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngine
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
 
Broadleaf Presents Thymeleaf
Broadleaf Presents ThymeleafBroadleaf Presents Thymeleaf
Broadleaf Presents Thymeleaf
 
Php
PhpPhp
Php
 
Solr integration in Magento Enterprise
Solr integration in Magento EnterpriseSolr integration in Magento Enterprise
Solr integration in Magento Enterprise
 
Drupal Development (Part 2)
Drupal Development (Part 2)Drupal Development (Part 2)
Drupal Development (Part 2)
 
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
 
第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource
 
Solr Anti Patterns
Solr Anti PatternsSolr Anti Patterns
Solr Anti Patterns
 
21. CodeIgniter search
21. CodeIgniter search21. CodeIgniter search
21. CodeIgniter search
 
Elasticsearch and Symfony Integration - Debarko De
Elasticsearch and Symfony Integration - Debarko DeElasticsearch and Symfony Integration - Debarko De
Elasticsearch and Symfony Integration - Debarko De
 
DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7
 
Why Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary ThingWhy Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary Thing
 

More from Acquia

Acquia_Adcetera Webinar_Marketing Automation.pdf
Acquia_Adcetera Webinar_Marketing Automation.pdfAcquia_Adcetera Webinar_Marketing Automation.pdf
Acquia_Adcetera Webinar_Marketing Automation.pdf
Acquia
 
Acquia Webinar Deck - 9_13 .pdf
Acquia Webinar Deck - 9_13 .pdfAcquia Webinar Deck - 9_13 .pdf
Acquia Webinar Deck - 9_13 .pdf
Acquia
 
Taking Your Multi-Site Management at Scale to the Next Level
Taking Your Multi-Site Management at Scale to the Next LevelTaking Your Multi-Site Management at Scale to the Next Level
Taking Your Multi-Site Management at Scale to the Next Level
Acquia
 
CDP for Retail Webinar with Appnovation - Q2 2022.pdf
CDP for Retail Webinar with Appnovation - Q2 2022.pdfCDP for Retail Webinar with Appnovation - Q2 2022.pdf
CDP for Retail Webinar with Appnovation - Q2 2022.pdf
Acquia
 
May Partner Bootcamp 2022
May Partner Bootcamp 2022May Partner Bootcamp 2022
May Partner Bootcamp 2022
Acquia
 
April Partner Bootcamp 2022
April Partner Bootcamp 2022April Partner Bootcamp 2022
April Partner Bootcamp 2022
Acquia
 
How to Unify Brand Experience: A Hootsuite Story
How to Unify Brand Experience: A Hootsuite Story How to Unify Brand Experience: A Hootsuite Story
How to Unify Brand Experience: A Hootsuite Story
Acquia
 
Using Personas to Guide DAM Results: How Life Time Pumped Up Their UX and CX
Using Personas to Guide DAM Results: How Life Time Pumped Up Their UX and CXUsing Personas to Guide DAM Results: How Life Time Pumped Up Their UX and CX
Using Personas to Guide DAM Results: How Life Time Pumped Up Their UX and CX
Acquia
 
Improve Code Quality and Time to Market: 100% Cloud-Based Development Workflow
Improve Code Quality and Time to Market: 100% Cloud-Based Development WorkflowImprove Code Quality and Time to Market: 100% Cloud-Based Development Workflow
Improve Code Quality and Time to Market: 100% Cloud-Based Development Workflow
Acquia
 
September Partner Bootcamp
September Partner BootcampSeptember Partner Bootcamp
September Partner Bootcamp
Acquia
 
August partner bootcamp
August partner bootcampAugust partner bootcamp
August partner bootcamp
Acquia
 
July 2021 Partner Bootcamp
July  2021 Partner BootcampJuly  2021 Partner Bootcamp
July 2021 Partner Bootcamp
Acquia
 
May Partner Bootcamp
May Partner BootcampMay Partner Bootcamp
May Partner Bootcamp
Acquia
 
DRUPAL 7 END OF LIFE IS NEAR - MIGRATE TO DRUPAL 9 FAST AND EASY
DRUPAL 7 END OF LIFE IS NEAR - MIGRATE TO DRUPAL 9 FAST AND EASYDRUPAL 7 END OF LIFE IS NEAR - MIGRATE TO DRUPAL 9 FAST AND EASY
DRUPAL 7 END OF LIFE IS NEAR - MIGRATE TO DRUPAL 9 FAST AND EASY
Acquia
 
Work While You Sleep: The CMO’s Guide to a 24/7/365 Lead Machine
Work While You Sleep: The CMO’s Guide to a 24/7/365 Lead MachineWork While You Sleep: The CMO’s Guide to a 24/7/365 Lead Machine
Work While You Sleep: The CMO’s Guide to a 24/7/365 Lead Machine
Acquia
 
Acquia webinar: Leveraging Drupal to Bury Your Sales Team In B2B Leads
Acquia webinar: Leveraging Drupal to Bury Your Sales Team In B2B LeadsAcquia webinar: Leveraging Drupal to Bury Your Sales Team In B2B Leads
Acquia webinar: Leveraging Drupal to Bury Your Sales Team In B2B Leads
Acquia
 
April partner bootcamp deck cookieless future
April partner bootcamp deck  cookieless futureApril partner bootcamp deck  cookieless future
April partner bootcamp deck cookieless future
Acquia
 
How to enhance cx through personalised, automated solutions
How to enhance cx through personalised, automated solutionsHow to enhance cx through personalised, automated solutions
How to enhance cx through personalised, automated solutions
Acquia
 
DRUPAL MIGRATIONS AND DRUPAL 9 INNOVATION: HOW PAC-12 DELIVERED DIGITALLY FOR...
DRUPAL MIGRATIONS AND DRUPAL 9 INNOVATION: HOW PAC-12 DELIVERED DIGITALLY FOR...DRUPAL MIGRATIONS AND DRUPAL 9 INNOVATION: HOW PAC-12 DELIVERED DIGITALLY FOR...
DRUPAL MIGRATIONS AND DRUPAL 9 INNOVATION: HOW PAC-12 DELIVERED DIGITALLY FOR...
Acquia
 
Customer Experience (CX): 3 Key Factors Shaping CX Redesign in 2021
Customer Experience (CX): 3 Key Factors Shaping CX Redesign in 2021Customer Experience (CX): 3 Key Factors Shaping CX Redesign in 2021
Customer Experience (CX): 3 Key Factors Shaping CX Redesign in 2021
Acquia
 

More from Acquia (20)

Acquia_Adcetera Webinar_Marketing Automation.pdf
Acquia_Adcetera Webinar_Marketing Automation.pdfAcquia_Adcetera Webinar_Marketing Automation.pdf
Acquia_Adcetera Webinar_Marketing Automation.pdf
 
Acquia Webinar Deck - 9_13 .pdf
Acquia Webinar Deck - 9_13 .pdfAcquia Webinar Deck - 9_13 .pdf
Acquia Webinar Deck - 9_13 .pdf
 
Taking Your Multi-Site Management at Scale to the Next Level
Taking Your Multi-Site Management at Scale to the Next LevelTaking Your Multi-Site Management at Scale to the Next Level
Taking Your Multi-Site Management at Scale to the Next Level
 
CDP for Retail Webinar with Appnovation - Q2 2022.pdf
CDP for Retail Webinar with Appnovation - Q2 2022.pdfCDP for Retail Webinar with Appnovation - Q2 2022.pdf
CDP for Retail Webinar with Appnovation - Q2 2022.pdf
 
May Partner Bootcamp 2022
May Partner Bootcamp 2022May Partner Bootcamp 2022
May Partner Bootcamp 2022
 
April Partner Bootcamp 2022
April Partner Bootcamp 2022April Partner Bootcamp 2022
April Partner Bootcamp 2022
 
How to Unify Brand Experience: A Hootsuite Story
How to Unify Brand Experience: A Hootsuite Story How to Unify Brand Experience: A Hootsuite Story
How to Unify Brand Experience: A Hootsuite Story
 
Using Personas to Guide DAM Results: How Life Time Pumped Up Their UX and CX
Using Personas to Guide DAM Results: How Life Time Pumped Up Their UX and CXUsing Personas to Guide DAM Results: How Life Time Pumped Up Their UX and CX
Using Personas to Guide DAM Results: How Life Time Pumped Up Their UX and CX
 
Improve Code Quality and Time to Market: 100% Cloud-Based Development Workflow
Improve Code Quality and Time to Market: 100% Cloud-Based Development WorkflowImprove Code Quality and Time to Market: 100% Cloud-Based Development Workflow
Improve Code Quality and Time to Market: 100% Cloud-Based Development Workflow
 
September Partner Bootcamp
September Partner BootcampSeptember Partner Bootcamp
September Partner Bootcamp
 
August partner bootcamp
August partner bootcampAugust partner bootcamp
August partner bootcamp
 
July 2021 Partner Bootcamp
July  2021 Partner BootcampJuly  2021 Partner Bootcamp
July 2021 Partner Bootcamp
 
May Partner Bootcamp
May Partner BootcampMay Partner Bootcamp
May Partner Bootcamp
 
DRUPAL 7 END OF LIFE IS NEAR - MIGRATE TO DRUPAL 9 FAST AND EASY
DRUPAL 7 END OF LIFE IS NEAR - MIGRATE TO DRUPAL 9 FAST AND EASYDRUPAL 7 END OF LIFE IS NEAR - MIGRATE TO DRUPAL 9 FAST AND EASY
DRUPAL 7 END OF LIFE IS NEAR - MIGRATE TO DRUPAL 9 FAST AND EASY
 
Work While You Sleep: The CMO’s Guide to a 24/7/365 Lead Machine
Work While You Sleep: The CMO’s Guide to a 24/7/365 Lead MachineWork While You Sleep: The CMO’s Guide to a 24/7/365 Lead Machine
Work While You Sleep: The CMO’s Guide to a 24/7/365 Lead Machine
 
Acquia webinar: Leveraging Drupal to Bury Your Sales Team In B2B Leads
Acquia webinar: Leveraging Drupal to Bury Your Sales Team In B2B LeadsAcquia webinar: Leveraging Drupal to Bury Your Sales Team In B2B Leads
Acquia webinar: Leveraging Drupal to Bury Your Sales Team In B2B Leads
 
April partner bootcamp deck cookieless future
April partner bootcamp deck  cookieless futureApril partner bootcamp deck  cookieless future
April partner bootcamp deck cookieless future
 
How to enhance cx through personalised, automated solutions
How to enhance cx through personalised, automated solutionsHow to enhance cx through personalised, automated solutions
How to enhance cx through personalised, automated solutions
 
DRUPAL MIGRATIONS AND DRUPAL 9 INNOVATION: HOW PAC-12 DELIVERED DIGITALLY FOR...
DRUPAL MIGRATIONS AND DRUPAL 9 INNOVATION: HOW PAC-12 DELIVERED DIGITALLY FOR...DRUPAL MIGRATIONS AND DRUPAL 9 INNOVATION: HOW PAC-12 DELIVERED DIGITALLY FOR...
DRUPAL MIGRATIONS AND DRUPAL 9 INNOVATION: HOW PAC-12 DELIVERED DIGITALLY FOR...
 
Customer Experience (CX): 3 Key Factors Shaping CX Redesign in 2021
Customer Experience (CX): 3 Key Factors Shaping CX Redesign in 2021Customer Experience (CX): 3 Key Factors Shaping CX Redesign in 2021
Customer Experience (CX): 3 Key Factors Shaping CX Redesign in 2021
 

Recently uploaded

The History of Embeddings & Multimodal Embeddings
The History of Embeddings & Multimodal EmbeddingsThe History of Embeddings & Multimodal Embeddings
The History of Embeddings & Multimodal Embeddings
Zilliz
 
Connector Corner: Leveraging Snowflake Integration for Smarter Decision Making
Connector Corner: Leveraging Snowflake Integration for Smarter Decision MakingConnector Corner: Leveraging Snowflake Integration for Smarter Decision Making
Connector Corner: Leveraging Snowflake Integration for Smarter Decision Making
DianaGray10
 
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
maigasapphire
 
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
bellared2
 
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and DisadvantagesBLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
SAI KAILASH R
 
Generative AI Reasoning Tech Talk - July 2024
Generative AI Reasoning Tech Talk - July 2024Generative AI Reasoning Tech Talk - July 2024
Generative AI Reasoning Tech Talk - July 2024
siddu769252
 
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
shanihomely
 
Opencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of MünsterOpencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of Münster
Matthias Neugebauer
 
Mastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for SuccessMastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for Success
David Wilson
 
Acumatica vs. Sage Intacct _Construction_July (1).pptx
Acumatica vs. Sage Intacct _Construction_July (1).pptxAcumatica vs. Sage Intacct _Construction_July (1).pptx
Acumatica vs. Sage Intacct _Construction_July (1).pptx
BrainSell Technologies
 
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
FIDO Alliance
 
It's your unstructured data: How to get your GenAI app to production (and spe...
It's your unstructured data: How to get your GenAI app to production (and spe...It's your unstructured data: How to get your GenAI app to production (and spe...
It's your unstructured data: How to get your GenAI app to production (and spe...
Zilliz
 
The Impact of the Internet of Things (IoT) on Smart Homes and Cities
The Impact of the Internet of Things (IoT) on Smart Homes and CitiesThe Impact of the Internet of Things (IoT) on Smart Homes and Cities
The Impact of the Internet of Things (IoT) on Smart Homes and Cities
Arpan Buwa
 
Gen AI: Privacy Risks of Large Language Models (LLMs)
Gen AI: Privacy Risks of Large Language Models (LLMs)Gen AI: Privacy Risks of Large Language Models (LLMs)
Gen AI: Privacy Risks of Large Language Models (LLMs)
Debmalya Biswas
 
Computer HARDWARE presenattion by CWD students class 10
Computer HARDWARE presenattion by CWD students class 10Computer HARDWARE presenattion by CWD students class 10
Computer HARDWARE presenattion by CWD students class 10
ankush9927
 
Communications Mining Series - Zero to Hero - Session 3
Communications Mining Series - Zero to Hero - Session 3Communications Mining Series - Zero to Hero - Session 3
Communications Mining Series - Zero to Hero - Session 3
DianaGray10
 
Use Cases & Benefits of RPA in Manufacturing in 2024.pptx
Use Cases & Benefits of RPA in Manufacturing in 2024.pptxUse Cases & Benefits of RPA in Manufacturing in 2024.pptx
Use Cases & Benefits of RPA in Manufacturing in 2024.pptx
SynapseIndia
 
Finetuning GenAI For Hacking and Defending
Finetuning GenAI For Hacking and DefendingFinetuning GenAI For Hacking and Defending
Finetuning GenAI For Hacking and Defending
Priyanka Aash
 
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Zilliz
 
Step-By-Step Process to Develop a Mobile App From Scratch
Step-By-Step Process to Develop a Mobile App From ScratchStep-By-Step Process to Develop a Mobile App From Scratch
Step-By-Step Process to Develop a Mobile App From Scratch
softsuave
 

Recently uploaded (20)

The History of Embeddings & Multimodal Embeddings
The History of Embeddings & Multimodal EmbeddingsThe History of Embeddings & Multimodal Embeddings
The History of Embeddings & Multimodal Embeddings
 
Connector Corner: Leveraging Snowflake Integration for Smarter Decision Making
Connector Corner: Leveraging Snowflake Integration for Smarter Decision MakingConnector Corner: Leveraging Snowflake Integration for Smarter Decision Making
Connector Corner: Leveraging Snowflake Integration for Smarter Decision Making
 
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
 
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
 
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and DisadvantagesBLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
 
Generative AI Reasoning Tech Talk - July 2024
Generative AI Reasoning Tech Talk - July 2024Generative AI Reasoning Tech Talk - July 2024
Generative AI Reasoning Tech Talk - July 2024
 
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
 
Opencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of MünsterOpencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of Münster
 
Mastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for SuccessMastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for Success
 
Acumatica vs. Sage Intacct _Construction_July (1).pptx
Acumatica vs. Sage Intacct _Construction_July (1).pptxAcumatica vs. Sage Intacct _Construction_July (1).pptx
Acumatica vs. Sage Intacct _Construction_July (1).pptx
 
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
 
It's your unstructured data: How to get your GenAI app to production (and spe...
It's your unstructured data: How to get your GenAI app to production (and spe...It's your unstructured data: How to get your GenAI app to production (and spe...
It's your unstructured data: How to get your GenAI app to production (and spe...
 
The Impact of the Internet of Things (IoT) on Smart Homes and Cities
The Impact of the Internet of Things (IoT) on Smart Homes and CitiesThe Impact of the Internet of Things (IoT) on Smart Homes and Cities
The Impact of the Internet of Things (IoT) on Smart Homes and Cities
 
Gen AI: Privacy Risks of Large Language Models (LLMs)
Gen AI: Privacy Risks of Large Language Models (LLMs)Gen AI: Privacy Risks of Large Language Models (LLMs)
Gen AI: Privacy Risks of Large Language Models (LLMs)
 
Computer HARDWARE presenattion by CWD students class 10
Computer HARDWARE presenattion by CWD students class 10Computer HARDWARE presenattion by CWD students class 10
Computer HARDWARE presenattion by CWD students class 10
 
Communications Mining Series - Zero to Hero - Session 3
Communications Mining Series - Zero to Hero - Session 3Communications Mining Series - Zero to Hero - Session 3
Communications Mining Series - Zero to Hero - Session 3
 
Use Cases & Benefits of RPA in Manufacturing in 2024.pptx
Use Cases & Benefits of RPA in Manufacturing in 2024.pptxUse Cases & Benefits of RPA in Manufacturing in 2024.pptx
Use Cases & Benefits of RPA in Manufacturing in 2024.pptx
 
Finetuning GenAI For Hacking and Defending
Finetuning GenAI For Hacking and DefendingFinetuning GenAI For Hacking and Defending
Finetuning GenAI For Hacking and Defending
 
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
 
Step-By-Step Process to Develop a Mobile App From Scratch
Step-By-Step Process to Develop a Mobile App From ScratchStep-By-Step Process to Develop a Mobile App From Scratch
Step-By-Step Process to Develop a Mobile App From Scratch
 

Apache Solr Search Mastery

  • 1. Apache Solr Search Mastery Peter Wolanin and Robert Douglass 25. aug 13:30 Trellon
  • 2. We  hope  you  will  leave  having   learned  about: • What  is  Solr  and  how  do  you  run  it  locally • Ge9ng  Drupal  data  into  Solr • Changes  in  Drupal  7 • Field  API  integraAon • Searching  Solr  from  Drupal • Modifying  what’s  searched  and  the  results • Theming  search  results
  • 3. Drupal  Interacts  with  Solr  via  HTTP • Drupal  sends  data  to  Solr  as  XML  documents • Solr  accepts  documents  POSTed  to  /update • A  different  XML  can  be  POSTed  to  delete • Searching,  etc  are  GET  requests • If  something  is  not  working  as  expected,  you   can  try  searching  directly  in  Solr  via  URL • Solr  also  includes  admin  and  analysis  interfaces   (you  need  to  lock  this  down  for  producAon).
  • 4. Run  Solr  Using  the  Example  Dir Replace the schema.xml and solrconfig.xml with the ones from the Drupal module Invoke the start.jar: java -jar start.jar
  • 6. Schema:  Defines  Types  &  Fields <?xml version="1.0" encoding="UTF-8" ?> <schema name="drupal-0.9.5" version="1.2"> <types> ... </types> <fields> <!-- The document id is derived from a site-spcific key (hash) and the node ID like: $document->id = $hash . '/node/' . $node->nid; --> <field name="id" type="string" indexed="true" stored="true" required="true" /> <!-- These are the fields that correspond to a Drupal node. --> <field name="site" type="string" indexed="true" stored="true"/> <field name="hash" type="string" indexed="true" stored="true"/> <field name="url" type="string" indexed="true" stored="true"/> <field name="title" type="text" indexed="true" stored="true" termVectors="true" omitNorms="true"/> <field name="sort_title" type="sortString" indexed="true" stored="false"/> <field name="body" type="text" indexed="true" stored="true" termVectors="true"/> <field name="teaser" type="text" indexed="false" stored="true"/> ... </fields> <uniqueKey>id</uniqueKey> <!-- field for the QueryParser to use when an explicit fieldname is absent --> <defaultSearchField>body</defaultSearchField> <!-- SolrQueryParser configuration: defaultOperator="AND|OR" --> <solrQueryParser defaultOperator="AND"/> </schema>
  • 7. Schema:  Defines  Types  &  Fields <field name="id" type="string" indexed="true" stored="true" required="true" /> <!-- These are the fields that correspond to a Drupal node. --> <field name="site" type="string" indexed="true" stored="true"/> <field name="hash" type="string" indexed="true" stored="true"/>
  • 8. Dynamic  Fields  Provide  Flexibility <!-- Dynamic field definitions will be used if the name matches any of the patterns. The glob-like pattern in the name attribute must have "*" only at the start or the end. Longer patterns will be matched first. --> <dynamicField name="is_*" type="integer" indexed="true" stored="true" multiValued="false"/> <dynamicField name="im_*" type="integer" indexed="true" stored="true" multiValued="true"/> ... <dynamicField name="ss_*" type="string" indexed="true" stored="true" multiValued="false"/> <dynamicField name="ts_*" type="text" indexed="true" stored="true" multiValued="false" termVectors="true"/> <dynamicField name="ds_*" type="date" indexed="true" stored="true" multiValued="false"/> <dynamicField name="dm_*" type="date" indexed="true" stored="true" multiValued="true"/> <dynamicField name="tds_*" type="tdate"indexed="true" stored="true" multiValued="false"/> <dynamicField name="tdm_*" type="tdate"indexed="true" stored="true" multiValued="true"/> <dynamicField name="bm_*" type="boolean" indexed="true" stored="true" multiValued="true"/> <dynamicField name="bs_*" type="boolean" indexed="true" stored="true" multiValued="false"/> ... <!-- Sortable version of the dynamic string field --> <dynamicField name="sort_ss_*" type="sortString" indexed="true" stored="false"/> <copyField source="ss_*" dest="sort_ss_*"/> <!-- A random sort field --> <dynamicField name="random_*" type="rand" indexed="true" stored="true"/> <!-- This field is used to store node access records, as opposed to CCK field data --> <dynamicField name="nodeaccess*" type="integer" indexed="true" stored="false" multiValued="true"/> <dynamicField name="*" type="ignored" multiValued="true" />
  • 9. Dynamic  Fields  Provide  Flexibility <!-- Dynamic field definitions will be used if the name matches any of the patterns. The glob-like pattern in the name attribute must have "*" only at the start or the end. Longer patterns will be matched first. --> <dynamicField name="is_*" type="integer" indexed="true" stored="true" multiValued="false"/> <dynamicField name="im_*" type="integer" indexed="true" stored="true" multiValued="true"/>
  • 10. Dynamic  Fields  Provide  Flexibility <!-- Dynamic field definitions will be used if the name matches any of the patterns. The glob-like pattern in the name attribute must have "*" only at the start or the end. Longer patterns will be matched first. --> <dynamicField name="is_*" type="integer" indexed="true" stored="true" multiValued="false"/> <dynamicField name="im_*" type="integer" indexed="true" stored="true" multiValued="true"/> ... <dynamicField name="ss_*" type="string" indexed="true" stored="true" multiValued="false"/> <dynamicField name="ts_*" type="text" indexed="true" stored="true" multiValued="false" termVectors="true"/> <dynamicField name="ds_*" type="date" indexed="true" stored="true" multiValued="false"/> <dynamicField name="dm_*" type="date" indexed="true" stored="true" multiValued="true"/> <dynamicField name="tds_*" type="tdate"indexed="true" stored="true" multiValued="false"/> <dynamicField name="tdm_*" type="tdate"indexed="true" stored="true" multiValued="true"/> <dynamicField name="bm_*" type="boolean" indexed="true" stored="true" multiValued="true"/> <dynamicField name="bs_*" type="boolean" indexed="true" stored="true" multiValued="false"/> ... <!-- Sortable version of the dynamic string field --> <dynamicField name="sort_ss_*" type="sortString" indexed="true" stored="false"/> <copyField source="ss_*" dest="sort_ss_*"/> <!-- A random sort field --> <dynamicField name="random_*" type="rand" indexed="true" stored="true"/> <!-- This field is used to store node access records, as opposed to CCK field data --> <dynamicField name="nodeaccess*" type="integer" indexed="true" stored="false" multiValued="true"/> <dynamicField name="*" type="ignored" multiValued="true" />
  • 11. Dynamic  Fields  Provide  Flexibility <!-- Sortable version of the dynamic string field --> <dynamicField name="sort_ss_*" type="sortString" indexed="true" stored="false"/> <copyField source="ss_*" dest="sort_ss_*"/> <!-- This field is used to store node access records, as opposed to CCK field data --> <dynamicField name="nodeaccess*" type="integer" indexed="true" stored="false" multiValued="true"/> <dynamicField name="*" type="ignored" multiValued="true" />
  • 13. Use the factory method to get an object for building your queries: $query = apachesolr_drupal_query( $keys = '', $filters = '', $solrsort = '', $base_path = '', $solr = NULL );
  • 14. The actual class that is returned is determined by a Drupal variable: variable_get('apachesolr_query_class', array('apachesolr', 'Solr_Base_Query'));
  • 15. interface Drupal_Solr_Query_Interface { get_filters($name); has_filter($field, $value); add_filter($field, $value, $exclude); remove_filter($field, $value); ... }
  • 16. interface Drupal_Solr_Query_Interface { ... get_keys(); set_keys($keys); remove_keys(); ... }
  • 17. interface Drupal_Solr_Query_Interface { ... get_path(); get_url_queryvalues(); get_query_basic(); ... }
  • 18. interface Drupal_Solr_Query_Interface { ... get_available_sorts(); set_available_sort($field, $sort); get_solrsort(); set_solrsort($field, $direction); ... }
  • 19. interface Drupal_Solr_Query_Interface { ... add_subquery( Drupal_Solr_Query_Interface $query); remove_subquery( Drupal_Solr_Query_Interface $query); remove_subqueries(); ... }
  • 20. interface Drupal_Solr_Query_Interface { ... // Passes to the $solr object which // executes the search. search($keys = NULL); }
  • 22. Use the factory method to get an object for sending requests to Solr: $solr = apachesolr_get_solr($host, $port, $path);
  • 23. The actual class that is returned is determined by a Drupal variable: variable_get('apachesolr_service_class', array('apachesolr', 'Drupal_Apache_Solr_Service.php', 'Drupal_Apache_Solr_Service') );
  • 24. This allows you to customize the way search works by providing a different solr service class than the standard. variable_set('apachesolr_service_class', array('acquia_search', 'Acquia_Search_Service.php', 'Acquia_Search_Service') );
  • 25. http://code.google.com/p/solr-php-client/ class Apache_Solr_Service { addDocument( Apache_Solr_Document $document); addDocuments($documents); deleteById($id); deleteByQuery($rawQuery); ... }
  • 28. class Drupal_Apache_Solr_Service extends Apache_Solr_Service { getLuke(); getFields(); getStatsSummary(); ... }
  • 29. class Drupal_Apache_Solr_Service extends Apache_Solr_Service { // Takes control of the request sending // and headers - Drupal idiomatic. _makeHttpRequest(); }
  • 31. http://code.google.com/p/solr-php-client/ class Apache_Solr_Document { addField($key, $value, $boost); setMultiValue($key, $value, $boost); }
  • 32. Drupal  7  Changes   $query, $params $query->params $solr->search() $query->search() • Taxonomy  on  a  node  is  now  a  term  reference  field   (works  as  part  of  the  Field  API  integraAon). • Fixes  to  core  search  module  APIs  mean  that  some   hacks  are  gone:  e.g.  no,  hook_menu_alter;  we   can  set  apachesolr  as  the  default  via  search  UI.
  • 33. You  Can  Add  Any  Data  to  the  Index hook_apachesolr_update_index(&$document, $node, $namespace) • Used  to  add  more  data  to  a  document  before   it’s  sent  to  Solr. • Can  also  be  used  to  alter  or  replace  data  added   by  apachesolr  or  another  module. • This  is  it!  (it  works  like  an  _alter  hook).
  • 34. Image  Data  Using  Dynamic  Fields /** * Implementation of hook_apachesolr_update_index(). */ function apachesolr_image_apachesolr_update_index(&$document, $node, $namespace) { if ($node->type == 'image' && $document->entity == 'node') { $areas = array(); $sizes = image_get_derivative_sizes($node->images['_original']); foreach ($sizes as $name => $info) { $areas[$name] = $info['width'] * $info['height']; } asort($areas); $image_path = FALSE; foreach ($areas as $preset => $size) { $image_path = $node->images[$preset]; break; } if ($image_path) { $document->ss_image_relative = $image_path; // Support multi-site too. $document->ss_image_absolute = file_create_url($image_path); } } } /** * Implementation of hook_apachesolr_modify_query(). */ function apachesolr_image_apachesolr_modify_query($query, $caller) { // Also retrieve image thumbnail links. $query->params['fl'] .= ',ss_image_relative'; }
  • 35. Image  Data  Using  Dynamic  Fields if ($image_path) { $document->ss_image_relative = $image_path; } /** * Implement hook_apachesolr_modify_query(). */ function apachesolr_image_apachesolr_modify_query( $query, $caller) { // Also retrieve image thumbnail links. $query->params['fl'] .= ',ss_image_relative'; }
  • 36. UI  to  Exclude  Whole  Content  Types • ?q=admin/config/search/apachesolr/content-­‐bias
  • 37. Control  Indexing  More  Precisely   hook_apachesolr_node_exclude($node, $namespace) in_array($node->type, variable_get( 'apachesolr_exclude_comments_types', array())) hook_node_update_index($node) • hook_node_update_index  output  added  to  body. • We  can  create  mulAple  documents  from  one  node   (e.g.  document  per  comment). hook_apachesolr_document_handlers($type, $namespace)
  • 38. Field  API  IntegraAon • Most  of  the  Field  API  integraAon  follows   directly  from  the  6.x-­‐2.x  CCK  integraAon. • In  Drupal  7,  we  match  field  types,  rather  than   looking  at  the  widget. • By  default,  the  data  will  be  indexed  to  Solr  as   mulA-­‐valued,  and  named  combining  the  field   module  and  name  sm_$module_$fieldname
  • 39. Typically  need  4  things: • What  field  types  (or  field  instances)  to  look   for  during  indexing. • The  data  type  to  use  in  the  index   (index_type) • A  funcAon  for  extracAng  the  data  from  the   field  while  indexing  (indexing_callback). • A  funcAon  for  displaying  the  data  from  the   field  during  searches  (display_callback).
  • 40. Field  API  IntegraAon hook_apachesolr_field_mappings_alter (&$mappings) $mappings['list_text'] = array( 'display_callback' => 'apachesolr_fields_list_display_callback', 'indexing_callback' => 'apachesolr_fields_list_indexing_callback', 'index_type' => 'string', );
  • 43. Analysis of an apachesolr search request search_view() $response = $query->search(...) $results = apachesolr_search_process_response ($response,$final_query) theme('search_results', $results, ...)
  • 44. Analysis of an apachesolr search request search_view() $response = $query->search(...) $results = apachesolr_search_process_response ($response,$final_query) theme('search_results', $results, ...)
  • 45. hook_menu: defines custom search paths /arts /arts/undergraduate /search/apachesolr_search/? filters=type%3Acatalog%20 ss_faculty%3AAR%20sm_level %3AUndergraduate
  • 46. hook_menu: defines custom search paths /arts /arts/undergraduate /arts/undergraduate/courses
  • 47. hook_menu: defines custom search paths // Implements hook_menu(). function mcgill_menu() { $items['arts/undergraduate/courses'] = array( 'page callback' => 'mcgill_courses_search', 'access arguments' => array('search content'), 'type' => MENU_CALLBACK, ); return $items; }
  • 48. Analysis of an apachesolr search request search_view() $response = $query->search(...) $results = apachesolr_search_process_response ($response,$final_query) theme('search_results', $results, ...)
  • 53. hook_menu_alter: changes the page callback // Implements hook_menu_alter(). function mcgill_menu_alter(&$items) { if (isset($items['search/apachesolr_search/%menu_tail'])) { $items['search']['page callback'] = 'mcgill_page'; $items['search/apachesolr_search/%menu_tail']['page callback'] = 'mcgill_page'; } }
  • 54. Analysis of an apachesolr search request search_view() $response = $query->search(...) $results = apachesolr_search_process_response ($response,$final_query) theme('search_results', $results, ...)
  • 55. An example Solr request
  • 56. Analysis of an apachesolr search request search_view() $response = $query->search(...) $results = apachesolr_search_process_response ($response,$final_query) theme('search_results', $results, ...)
  • 58. Analysis of an apachesolr search request search_view() $response = $query->search(...) $results = apachesolr_process_response($response, ...) $results = apachesolr_search_process_response ($response,$final_query) theme('search_results', $results, ...)
  • 59. hook_apachesolr_prepare/modify_query($query) // Run hook_apachesolr_prepare_query($query). // Cache the built query. $current_query = apachesolr_current_query($query); // Run hook_apachesolr_modify_query($query).
  • 62. hook_apachesolr_prepare_query($query): set a default Solr sort parameter
  • 63. hook_apachesolr_prepare_query($query): set a default Solr sort parameter $query->set_available_sort('sort_ss_course_code', array( 'title' => t('Course code'), 'default' => 'asc', )); $query->remove_available_sort('created'); $query->remove_available_sort('sort_name'); $query->remove_available_sort('type');
  • 64. hook_apachesolr_prepare_query($query): set a default Solr sort parameter if (!isset($_GET['solrsort'])) { if ($query->get_keys()) { $query->set_solrsort('score', 'asc'); } else { $query->set_solrsort('sort_ss_course_code', 'asc'); } }
  • 66. Should I use hook_apachesolr_prepare_query or hook_apachesolr_modify_query? /arts/undergraduate/courses
  • 67. Should I use hook_apachesolr_prepare_query or hook_apachesolr_modify_query?
  • 68. Should I use hook_apachesolr_prepare_query or hook_apachesolr_modify_query?
  • 69. Should I use hook_apachesolr_prepare_query or hook_apachesolr_modify_query?
  • 70. Should I use hook_apachesolr_prepare_query or hook_apachesolr_modify_query?
  • 71. Should I use hook_apachesolr_prepare_query or hook_apachesolr_modify_query?
  • 72. hook_apachesolr_modify_query($query): set default Solr fq parameters // Add filters for FACULTY/LEVEL/courses paths. if ($facet = get_faculty_from_path()) { $query->add_filter('ss_faculty', $facet); } if ($facet = get_level_from_path()) { $query->add_filter('sm_level', $facet); }
  • 74. hook_apachesolr_prepare/modify_query($query) Set Solr parameters in $query->params $query->params['fl'] .= ',ss_course_code'; $query->params['facet.limit'] = -1;
  • 75. Analysis of an apachesolr search request search_view() $response = $query->search(...) $results = apachesolr_search_process_response ($response,$final_query) theme('search_results', $results, ...)
  • 76. Analysis of an apachesolr search request search_view() $response = $query->search(...) $results = apachesolr_search_process_response ($response,$final_query) theme('search_results', $results, ...)
  • 78. theme_apachesolr_search_snippets: sets the snippet // Default implementation in apachesolr_search.module. function theme_apachesolr_search_snippets($document, $snippets) { return implode(' ... ', $snippets) . ' ...'; }
  • 80. theme_apachesolr_search_snippets: sets the snippet // Custom implementation in template.php. function mcgill_apachesolr_search_snippets($document, $snippets) { return 'anything you want!'; }
  • 81. Analysis of an apachesolr search request search_view() $response = $query->search(...) $results = apachesolr_search_process_response ($response,$final_query) theme('search_results', $results, ...)
  • 82. search-result.tpl.php: renders a single search result <?php print $result['node']->ss_course_code; ?> If this is user input use check_plain() - Solr can send you back the same (unsafe) user input you index. See apachesolr_clean_text() if you want to index text without tags.
  • 83. Extra thanks to James McKinney For use of his slides and for ideas. jpmckinney on drupal.org http://evolvingweb.ca/