Skip to content

Reuters tutorial: step 4

James McKinney edited this page Jul 19, 2013 · 20 revisions

Table of Contents

Let’s add some tag clouds for each of the topics, organizations, and exchanges facet fields.

First, add the Solr parameters for faceting in reuters.js:

var params = {
  facet: true,
  'facet.field': [ 'topics', 'organisations', 'exchanges' ],
  'facet.limit': 20,
  'facet.mincount': 1,
  'f.topics.facet.limit': 50,
  'json.nl': 'map'
};
for (var name in params) {
  Manager.store.addByValue(name, params[name]);
}

Note: Several widgets in the next steps require json.nl to be set to map.

Note: If you are using your own Solr instance, you may want to change the value assigned to the facet.field key.

Create a new widget, TagcloudWidget.js, inheriting from AbstractFacetWidget:

(function ($) {
AjaxSolr.TagcloudWidget = AjaxSolr.AbstractFacetWidget.extend({
});
})(jQuery);

And add the JavaScript files:

<script src="../../lib/core/AbstractFacetWidget.js"></script>
<script src="widgets/TagcloudWidget.js"></script>

AbstractFacetWidget provides many convenient functions specific to faceting widgets, but you may alternatively inherit from AbstractWidget if you choose not to use those functions.

Now, add three widget instances, one for each facet field, to the Manager in reuters.js:

var fields = [ 'topics', 'organisations', 'exchanges' ];
for (var i = 0, l = fields.length; i < l; i++) {
  Manager.addWidget(new AjaxSolr.TagcloudWidget({
    id: fields[i],
    target: '#' + fields[i],
    field: fields[i]
  }));
}

Note: If you are using your own Solr instance, you may want to change the value assigned to fields. Moreover, you will have to rename the ID names of div class=“tagcloud” elements of the index.html file.

Any widget inheriting from AbstractFacetWidget takes a required field property, identifying the facet field the widget will handle. Note that, in our example, the target HTML element is conveniently named after the Solr field. This may not be the case in your application; set your field property accordingly.

Now, let’s implement the abstract method afterRequest, as we did for the ResultWidget:

afterRequest: function () {
  if (this.manager.response.facet_counts.facet_fields[this.field] === undefined) {
    $(this.target).html('no items found in current selection');
    return;
  }

  var maxCount = 0;
  var objectedItems = [];
  for (var facet in this.manager.response.facet_counts.facet_fields[this.field]) {
    var count = parseInt(this.manager.response.facet_counts.facet_fields[this.field][facet]);
    if (count > maxCount) {
      maxCount = count;
    }
    objectedItems.push({ facet: facet, count: count });
  }
  objectedItems.sort(function (a, b) {
    return a.facet < b.facet ? -1 : 1;
  });

  $(this.target).empty();
  for (var i = 0, l = objectedItems.length; i < l; i++) {
    var facet = objectedItems[i].facet;
    $(this.target).append(
      $('<a href="#" class="tagcloud_item"></a>')
      .text(facet)
      .addClass('tagcloud_size_' + parseInt(objectedItems[i].count / maxCount * 10))
      .click(this.clickHandler(facet))
    );
  }
}

There’s a lot going on here, but only two snippets have to do with AJAX Solr:

this.manager.response.facet_counts.facet_fields[this.field]

this.manager.response should be familiar from the ResultWidget in Step 2. this.field is the field property we set when adding the widget instance to the manager. So, in this snippet, we are inspecting the facet data for that field in the Solr response. The other snippet of interest is:

this.clickHandler(facet)

clickHandler is one of the convenient functions provided by AbstractFacetWidget. It tries to add a fq parameter corresponding to the widget’s facet field and the given facet value; if successful, it sends a request to Solr. For a full list of functions defined by AbstractFacetWidget, see the documentation.

[What we have so far]

Now that we’re adding fq parameters, it would be nice to display the current filters.