Removing filters from faceting results

Let's assume for the purpose of this recipe, you have an application that can search for companies within a city and a state. However, the requirements say that not only should you show the search results, but also the number of companies in each city and the number of companies in each state (to say in the Solr way—you want to exclude the filter query from the faceting results). Can Solr do this efficiently ? Sure it can, and this recipe will show you how to do it.

Getting ready

Before you start reading this recipe, let's take a look at the Getting the number of documents with the same field value recipe of this chapter.

How to do it...

  1. As usual we start with a very simple index structure that contains four fields. We do this by adding the following section to the schema.xml file:
    <field name="id" type="string" indexed="true" stored="true" required="true" />
    <field name="name" type="text_general" indexed="true" stored="true" />
    <field name="city" type="string" indexed="true" stored="true" />
    <field name="state" type="string" indexed="true" stored="true" />
  2. The second step would be to index the following example data:
    <add>
     <doc>
      <field name="id">1</field>
      <field name="name">Company 1</field>
      <field name="city">New York</field>
      <field name="state">New York</field>
     </doc>
     <doc>
      <field name="id">2</field>
      <field name="name">Company 2</field>
      <field name="city">New Orleans</field>
      <field name="state">Luiziana</field>
     </doc>
     <doc>
      <field name="id">3</field>
      <field name="name">Company 3</field>
      <field name="city">New York</field>
      <field name="state">New York</field>
     </doc>
     <doc>
      <field name="id">4</field>
      <field name="name">Company 4/field>
      <field name="city">New York</field>
      <field name="state">New York</field>
     </doc>
    </add>
  3. Let's suppose that our hypothetical user searches for the word company, and we tell our application that the user needs the companies matching the word in the state of New York. However, we would like to show the number of documents matching the word company in all the states and in the cities of all the states. In that case, the query that will fulfill our requirement should look as follows:
    http://localhost:8983/solr/cookbook/select?q=name:company&facet=true &fq={!tag=stateTag}state:"New York"&facet.field={!ex=stateTag}city&facet.field={!ex=stateTag}state

    The result for the preceding query will look as follows:

    <?xml version="1.0" encoding="UTF-8"?>
    <response>
     <lst name="responseHeader">
      <int name="status">0</int>
      <int name="QTime">1</int>
      <lst name="params">
       <str name="q">name:company</str>
       <arr name="facet.field">
        <str>{!ex=stateTag}city</str>
        <str>{!ex=stateTag}state</str>
       </arr>
       <str name="fq">{!tag=stateTag}state:"New York"</str>
       <str name="facet">true </str>
      </lst>
     </lst>
     <result name="response" numFound="3" start="0">
      <doc>
       <str name="id">1</str>
       <str name="name">Company 1</str>
       <str name="city">New York</str>
       <str name="state">New York</str>
       <long name="_version_">1471070665204301824</long></doc>
      <doc>
       <str name="id">3</str>
       <str name="name">Company 3</str>
       <str name="city">New York</str>
       <str name="state">New York</str>
       <long name="_version_">1471070665210593280</long></doc>
      <doc>
       <str name="id">4</str>
       <str name="name">Company 4</str>
       <str name="city">New York</str>
       <str name="state">New York</str>
       <long name="_version_">1471070665210593281</long></doc>
     </result>
     <lst name="facet_counts">
      <lst name="facet_queries"/>
      <lst name="facet_fields">
       <lst name="city">
        <int name="New York">3</int>
        <int name="New Orleans">1</int>
       </lst>
       <lst name="state">
        <int name="New York">3</int>
        <int name="Luiziana">1</int>
       </lst>
      </lst>
      <lst name="facet_dates"/>
      <lst name="facet_ranges"/>
     </lst>
    </response>

Now let's see how it works.

How it works...

The index structure is pretty simple—it contains four fields that describe the company. The search will be performed against the name field, while the filtering and the faceting will be done with the use of the state and the city fields.

So, let's get on with the query. As you can see, we have some typical elements there. First of all we have the q parameter, which just tells Solr where and what to search for. Then, the facet=true parameter enables the faceting mechanism. Following that you have a strange looking filter query (the fq parameter) with the value of fq={!tag=stateTag}state:"New York". It tells Solr to only show those results that have both New York in the state field, but not the results that have either of them. By adding the {!tag=stateTag} part, we basically gave that filter query a name (stateTag) that we will use further.

Now look at the two facet.field parameters. Our requirement was to show the number of companies in all states and in all cities. The only thing that was preventing us from getting those numbers was the filter query that we added to the query. So, let's exclude it from the faceting results. How do we do it? It's simple—just add {!ex=stateTag} to the beginning of each of the facet.field parameters like this: facet.field={!ex=stateTag}city. It tells Solr to exclude the filter with the passed name.

As you can see in the results list, we got the numbers correctly, which means that the exclude works as intended.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.228.78