All posts by Rebecca Tang

Job Shadowing: hosting high school students from Balboa High School

On Thursday October 26, 2017, the Library and the CKM hosted job shadowing for high school students for the first time!

Two students, Kelly and Jane, both Juniors from Balboa High School, visited us and spent the day learning about what it is like to work as a programmer.  Kelly and Jane are part of the Game Design Academy at Balboa High School.  The Game Design Academy is the path way for students who are interested in engineering and programming.  Kelly and Jane have not had any programming experience yet.  They will start programming classes next semester.

They started the day off with a tour of the library with Jim.  Then they attended the weekly meeting with the Industry Documents Library team.  During the meeting, they learned about about the IDL project, databases, and search index.

Then they attended Illios code jam with the Illios team where they got a front end programming primer from Jason and listened in as the Illios team discussed ways to improve their UI.

During lunch, Kelly and Jane asked us 10 questions from their teacher.  We had fun discovering that most programmers did not have a college degree in programming.  We also talked about the qualities that help us succeed at our jobs,  the things we expect from a good leader, and Sascha gave them the best advise on exploring everything that is not related to their chosen career because every extracurricular activity they participate in will eventually help them succeed in their career.


We finished off the day at the Maker’s Lab where Dylan gave the students a great overview of the various maker’s projects.  Kelly and Jane were introduced to two different types of 3D printers and saw the clavicle bones that a UCSF doctor printed.  They also talked to second year medical student Parth who mentioned his own experience job shadowing at hospitals while he was in high school.  Since Jane is also interested in a career in medicine, Parth gave her the information on how to job shadow at ZSFG.

We look forward to hosting another job shadowing day in the spring and working with one to two interns during the summer!



Solr/Blacklight highlighting and upgrading Blacklight from 5.1.0 to 5.3.0

Last week, I ran into a highlighting issue with Blacklight where clicking on a facet results in the blanking out of the values of the fields with highlighting turned on.  I debugged into the Blacklight 5.3.0 gem and found that in document_presenter.rb, it displays the highlight snippet from Solr response highlighting.  If nothing is returned from Solr highlighting, then it returns null to the view.

when (field_config and field_config.highlight)
   # retrieve the document value from the highlighting response         @document.highlight_field(field_config.field).map { |x| x.html_safe } if @document.has_highlight_field? field_config.field

This seemed strange to me because I couldn’t always guarantee that Solr returned something for the highlighting field.  So I posted to the Blacklight user’s group with my question.  I got a response right away (thank you!) and it turns out Blacklight inherits Solr’s highlighting behavior.  In order to always return a value for the highlighting field, an hl.alternateField is needed in the Solr configuration.

Here’s my code in the catalog_controller.rb that enables highlighting:

configure_blacklight do |config|
    ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params
    config.default_solr_params = { 
      :qt => 'search',
      :rows => 10,
      :fl => 'dt pg bn source dd ti id score',
      :"hl.fl" => 'dt pg bn source',
      :"f.dt.hl.alternateField" => 'dt',
      :"" => 'pg',
      :"" => 'bn',
      :"f.source.hl.alternateField" => 'source',
      :"hl.simple.pre" => '',
      :"" => '',
      :hl => true


    config.add_index_field 'dt', :label => 'Document type', :highlight => true
    config.add_index_field 'bn', :label => 'Bates number', :highlight => true
    config.add_index_field 'source', :label => 'Source', :highlight => true
    config.add_index_field 'pg', :label => 'Pages', :highlight => true


Another issue I ran into was upgrading from Blacklight 5.1.0 to 5.3.0. It does have an impact on the solrconfig.xml file.  It took me a bit of time to figure out the change that’s needed.

In the solrconfig.xml that ships with Blacklight 5.1.0, the standard requestHandler is set as the default.

<requestHandler name="standard" default="true" />

This means if the qt parameter is not passed in, Solr will use this request handler.  In fact, with version 5.1.0, which request handler is set as default is not important at all. In my solrconfig.xml, my own complex request handler is set as default and it did not cause any issues.

But in 5.3.0 the search request handler must be set as the default:

<requestHandler name="search" default="true">

This is because Blacklight now issues a Solr request like this:[Solr_server]:8983/solr/[core_name]/select?wt=ruby. Notice the absence of the qt parameter. The request is routed to the default search request handler to retrieve and facet records.

Working with Blacklight Part 3 – Linking to Your Solr Index

We are using Blacklight to provide a search interface for a Solr index.  I expected it to be super straightforward to plug in our Solr index to the Blacklight configuration.  It wasn’t quite the case! Most of the basic features do plugin nicely, but if you use more advanced Solr features (like facet pivot) or if your solrconfig.xml differs from the Blacklight example solrconfig.xml file, then you are out of luck.  There is not currently much documentation to help you out.

SolrConfig.xml – requestDispatcher

After 3.6, Solr ships with <requestDispatcher handleSelect=”false”> in the solrconfig.xml file.  But Blacklight works with <requestDispatcher handleSelect=”true”>, and passes in the parameter qt (request handler) explicitly .  An example of a SOLR request sent by Blacklight looks like this:

/select request handler should not be defined in solrconfig.xml. This allows the request dispatcher to dispatch to the request handler specified in the qt parameter. Blacklight, by default, expects a search and a document request handler (note the absence of /).

We could override the controller code for Blacklight to call our request handlers.  But a simpler solution is to update the solrconfig.xml to follow the Blacklight convention.

The ‘document’ Request Handler and id Passing

Blacklight expects there to be a document request handler defined in the solrconfig.xml file like this:

<!-- for requests to get a single document; use id=666 instead of q=id:666-->   
<requestHandler name="document" class="solr.SearchHandler">
    <lst name="defaults">
        <str name="echoParams">all</str>       
        <str name="fl">*</str>       
        <str name="rows">1</str>       
        <str name="q">{!raw f=id v=$id}</str> <!-- use id=666 instead of q=id:666 -->

As the comment says, Blacklight will pass in the request to SOLR in the format of id=666 instead of q=id:666.  It achieves this by using the SOLR raw query parser.  However, this only works if your unique id is a String.  In our case, the unique id is a long and passing in id=666 does not return anything in the SOLR response.

There are two ways to solve this issue.  The first is to rebuild the index and change the id type from long to String.  The other is to override solr_helper.rb to pass in q=id:xxx instead of id=xxx.  And the code snippet is below.

  require "#{Blacklight.root}/lib/blacklight/solr_helper.rb"
  module Blacklight::SolrHelper
  extend ActiveSupport::Concern

  # returns a params hash for finding a single solr document (CatalogController #show action)
  # If the id arg is nil, then the value is fetched from params[:id]
  # This method is primary called by the get_solr_response_for_doc_id method.
  def solr_doc_params(id=nil)
    id ||= params[:id]
    p = blacklight_config.default_document_solr_params.merge({
      #:id => id # this assumes the document request handler will map the 'id' param to the unique key field
      :q => "id:" + id.to_s
    p[:qt] ||= 'document'


Getting Facet Pivot to work

In our index, we have a top-level facet called industry and a child facet called source that should be displayed in a hierarchical tree.    It should look something like:
Screen Shot 2014-03-04 at 2.48.23 PM

The correct configuration is in the code snippet below.

    config.add_facet_field 'industry', :label => 'Industry', :show => false
# Source
    config.add_facet_field 'source_facet', :label => 'Source', :show => false
#Industry -> Source
    config.add_facet_field 'industry_source_pivot_field', :label => 'Industry/Source',   :pivot => ['industry', 'source_facet']

You must add the two base fields  (Industry and Source) to the catalog_controller.rb file and set :show => false if they should not be displayed.  And it usually is the case since the data is already displayed in the pivot tree.  The current documentation on Blacklight facet pivot support makes it seem like only the last line is needed.  But if only the last line is defined, then the facet pivot will render correctly in the refine panel and it makes you think that facet pivot is working OK. But when you click on the facet, you will get an error, “undefined method ‘label’ for nil:NilClass”:

Screen Shot 2014-03-04 at 2.38.24 PM