---
title: "Custom search forms with Views and Fastsearch"
url: "/articles/custom-search-forms-with-views-and-fastsearch"
type: article
date: 2007-08-20
updated: 2016-04-07
---

# Custom search forms with Views and Fastsearch

#  Custom search forms with Views and Fastsearch 

 Drupal custom search

 By

 [  Robert Douglass   ](/about/robert-douglass) 

 August 20, 2007

  

In this article I show you how to use views and views\_fastsearch to make customized search forms that fit your exact needs. Have you ever wanted to restrict search to just one or two content types? Or search on only an exact set of nodes, say all articles written by a given author? Views and views\_fastsearch are the right tools for the job.This article applies to [Drupal 5.x](http://drupal.org/download), plus the [views 1.6](http://drupal.org/node/159390) and the [views fastsearch 5.x-1.x-dev](http://drupal.org/node/102088) modules.

*UPDATE: As of August 21, 2007, there is no 5.x-1.2 release of views\_fastsearch. Until that release is completed, use the 5.x-1.x-dev version of the module to see the features described in this article.*

Drupal's search module contains a powerful indexer which makes keyword searching efficient and accurate. On its own, the search module provides either a plain vanilla search field, or the [advanced search form](http://drupal.org/node/28159), but doesn't provide a mechanism for customizing the offerings. It is an either/or proposition. The views module is well loved for its ability to let you define a custom set of content on your site, and through the use of exposed filters, allow the site visitor to narrow the selection even further. These two modules can be glued together and made to cooperate using the views fastsearch module. In this article I show how to build a search form that has filters for taxonomy terms and content types.

## What is a view?

For all the talk about the views module, it is often not fully understood what a view actually is. In its most basic form a view is a set of content (nodes). In fact, when you create a new view, it is, in its initial state, the set of all of the nodes on your site. All of the other stuff that you may do that view will either narrow the set of nodes to be smaller and more focused, or define how those nodes should be displayed.

One of the best features of views is its filters. Once you've defined the initial set of content that the view is dealing with, filters can be used to narrow the set. By exposing the filter to the end user as a form element you empower your visitors to slice and dice the view to taste, and find exactly the content that they are looking for.

## What is views fastsearch?

The views fastsearch is one such filter. It allows you to start with a view and narrow the set of content based on keywords. It utilizes the very search index that the search module has built, but it restricts its search to the content set defined by the view. It also uses clever SQL to do the actual searching quicker than the search module, thus the "fast" aspect.

The definition of a view as a set of content is a practical definition to work with. It makes it clear that if our goal is to replace Drupal's standard search (which searches all of the *published* content on your site), the default view (all content) is a good starting place. Once we create a new view, the steps that remain are to narrow the set (limit it to published content), tell it how to present the results (as search results), and to expose the views fastsearch keyword filter so that users can enter their search keywords. We will then have a near identical replacement for Drupal's standard search.

## Setting up

To get set up I installed the search, [views](http://drupal.org/node/159390) and [views\_fastsearch](http://drupal.org/node/136690) modules. I created a small amount of content by hand. There are five nodes in total, and they all contain the word *Drupal*. I kept the two default content types, Story and Page, that are present in a fresh Drupal 5.2 install. I created a taxonomy vocabulary called *Drupal topic* with the terms *core*, *modules*, and *themes*. I ran cron.php once to make sure that the search index has been built.

First I will show you how to search this content with views fastsearch, after which I will show how a customized form can be built to filter by taxonomy and content type.

## Building a view that works like normal search

Once the modules are installed and some content has been created, it's time to create a view. This is done by navigating to *Administer-&gt;Site building-&gt;Views-&gt;Add*.

### Basic configuration

   

   

 ![views1-annotated.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/views1-annotated.png.webp?itok=WwMJFufK "views1-annotated.png")

 *Figure I: Name, Access and Description*

Fill out the following fields:

1. **Name**: This is the machine name of the view. I used *content\_search*
2. **Access**: You have the chance to limit access to this view by role. Leaving all roles unchecked is equivalent to allowing access to everyone, which is the typical configuration for site search.
3. **Description**: A brief description of the view that will be useful to you as an administrator later. It appears on the views administration page and is never seen by your end users.

### Provide a page view

We need to tell views to provied a page view for the search results.

   

   

 ![views2-annotated.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/views2-annotated.png.webp?itok=mhJnyWiS "views2-annotated.png")

 *Figure II: Page View, URL, View Type, Title, Use Pager and Nodes per Page*

1. **Provide Page View**: This must be checked in order for views to provide a page view.
2. **URL**: This is actually the Drupal path (the 'q' parameter), not a full URL. It should not conflict with existing Drupal paths, so using *search* here will cause problems. I chose *fastsearch*, but you can use any path you choose. This path can be aliased using the path module.
3. **View Type**: This should be *Search Results* to emulate traditional Drupal search. Feel free to try the other options, though. For *Table View* or *List View* you will need to also add the fields which you wish to be displayed.
4. **Title**: This will be the page title for the search page. This can be whatever you want. I chose "Search by keyword, type and taxonomy".
5. **Use Pager**: This is important if you want your end user to be able to see more than the first page of search results.
6. **Nodes per Page**: Unlike the core search module, views allows you to define how many results per page are displayed. If you are the type who likes Google to show 50 results per page, you can set this number to 50 and enjoy.

### Adding fields

For the *Search Results* view type the only field that is needed is the *Search Score* field. No configuration is need on the field. If you wish to experiment with other view types (*Table*, for example), you need to explicitly add each field that should be displayed.

   

   

 ![views3.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/views3.png.webp?itok=mAgn4U58 "views3.png")

 *Figure III: Search Score*

### Filters and exposed filters

Nearly every view that you ever create should be filtered to only include published material. The views fastsearch is also a filter (*Search: Fast Index*). Both of these are added in the filters section. The fastsearch filter should also be exposed to the end user (otherwise they can't enter their search keywords!)

   

   

 ![views0-annotated.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/views0-annotated.png.webp?itok=aP241obw "views0-annotated.png")

 *Figure IV: Node: Published, Search: Fast Index*

In the *Filters* fieldset:

1. **Node: Published**: This limits the set of searchable nodes to those that are published. *Yes* means that the set should be filtered to only include those nodes that are published. If you wanted to build an interface for searching through the *un*published nodes on your site, you could set this to *No*.
2. **Search: Fast Index**: This is the filter that says "take the set of nodes in this view and reduce it to only those which have a certain search term in the search index."
3. After adding the *Search: Fast Index* to the filters, it will have an *Expose* button. Use that button to add the filter to the the *Exposed Filters* fieldset:

    - **Label**: This is text that will appear as a label on the form element that instructs the end user what the field should be used for. I chose "Keyword search".
    - **Optional**: This determines whether a value has to be given for this filter to get any results at all. When unchecked, as in [Figure IV](#figure4), it is not optional, and no nodes will be returned by the view if the *Keyword search* field is left empty. This is the same behavior that the Drupal core search module has, as well as Google and other search engines. First you are presented with a search screen and no results. Only after you type some keywords and submit the form are search results shown. If the **Optional** box were checked, it would instruct the view to ignore this filter if no value is present. The view would then show its default set of content (which is all content on the site in this case), and someone coming to the search screen would be confronted with a full array of search results even though they have not yet searched for anything. As you'll see later in this article, this creates a point of conflict when we add and expose further filters.
    - **Filter settings Default**: When checked, this tells the filter to inherit default settings from the *Value* field for this filter in the *Filters* fieldset.
    - **Force Single**: Some filters can have multiple values (eg. the taxonomy filter could have *core* and *modules* selected). Checking the *Force Single* checkbox limits the end user to only one choice. Practically, this changes the form element from a multiple select to a single select.
    - **Lock Operator**: Some filters have multiple possible operators (eg. AND/OR). When this is the case, the default behavior is to show an extra form element which specifies the operator. This is usually too much for the normal end user (but can be pure candy for power users), and you can hide that extra form element by checking *Lock Operator*

### Sorting

Last but not least, it is important to tell views how to sort the results. If you think about this in terms of Google or Yahoo!, you'll realize that search is not just a matter of identifying the right results, but also making sure that the right ones appear at the top of the list for the convenience of the person searching. This task falls to the scores that have been created by the search index. Adding a *Search Score* sort to our view will guarantee that the most relevant results are displayed first. Make sure that the sort is set to *Descending*, or you'll end up presenting the least relevant items first!

   

   

 ![views6.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/views6.png.webp?itok=yTUK3PUY "views6.png")

 *Figure V: Search Score, Descending*

## The search results - Part I

Now if you visit example.com/fastsearch you should see a nice search form waiting for you. Since the core search module is also active, we can compare the search results produced by the two. In my tests, the [scoring factors](https://www.lullabot.com/articles/drupals-search-module-and-scoring-factors) affect the ordering of the results differently for fastsearch and core search. Overall, the core search handles scoring in a more sophisticated manner than the fast search filter. Fast search makes up for this, though, by allowing more control over the set of content being searched, and also by defining a hook that lets modules add their own scoring factors to search results.

   

   

 ![searchresults-annotated.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/searchresults-annotated.png.webp?itok=_1jNH35R "searchresults-annotated.png")

 *Figure VI: Search results compared*

## Extending the search form by adding filters

Now it's time to add two more filters to the view so that we can narrow the results based on content type and taxonomy term. Go back to the view and open up its edit tab.

   

   

 ![views4-annotated.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/views4-annotated.png.webp?itok=xVcgLZyr "views4-annotated.png")

 *Figure VII: Taxonomy Terms for a vocabulary, Node: Type*

In the *Filters* fieldset, add two more filters:

1. **Taxonomy: Terms for Drupal topic**: *Drupal topic* is the name of the taxonomy vocabulary in my test data. Different *Terms for ...* filters will appear for your specific vocabularies
2. **Node: Type**: This filters on the node type, and you must select all of the options in *Value* that you want to be available to the end user. In my test data there are only two content types, *Story* and *Page*, and I want the end user to be able to search in both. One common feature request on Drupal.org is to limit search to one or more content types, or to exclude a content type altogether. With this filter you can achieve just that.

Now click *Expose* on both of the new filters to make form elements available to the end user.

   

   

 ![views5-annotated.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/views5-annotated.png.webp?itok=I7i7lsqq "views5-annotated.png")

 *Figure VIII: Search: Fast Index (Optional) and exposed filters*

1. **Search: Fast Index - Optional**: I mentioned in the discussion of the [Optional](#optional) checkbox in the *Exposed Filters* fieldset, there is some conflict between the *Search: Fast Index* field and the other filters. You'll notice in [Figure VIII](#figure8) that *Optional* has now been checked - the search term is now indeed optional. This is done because it is a nice feature to be able to use the other two filters, *Drupal term* and *Type*, on their own. You can select all of the *Story* type content that is categorized as *core*, for example. If the *Search: Fast Index* filter is required, then this is impossible because you always have to enter a search term (thus narrowing the results to only that term). The drawback of making the filter optional is that the initial search page will show a set of results even before the user has entered any criteria. If this is disturbing to you, you'll need to make the field not optional and do without the functionality of filtering based on type and taxonomy alone.
2. **Taxonomy: Terms for Drupal topic**:
3. **Node: Type**: For both the taxonomy and the node type filters, the same applies. We want them to be optional so that the user can search with keyword alone. I chose the *Force Single* option because I like the cleanlier feel of a single select more than the multiple select. I chose *Lock Operator* because I don't think my site users necessarily want to think about AND/OR operators when searching.

## The search results - Part II

Now with two more exposed filters, we can do some very precise searching.

   

   

 ![search1.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/search1.png.webp?itok=GNrSKknB "search1.png")

 *Figure IX: All content in the themes category*

   

   

 ![search2.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/search2.png.webp?itok=3Izhk2k7 "search2.png")

 *Figure X: All content in the themes category that matches the search term "deco"*

   

   

 ![search3.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/search3.png.webp?itok=ACKH8-RB "search3.png")

 *Figure XI: All Story content in the themes category*

## Configuring the Views Fastsearch module

If you visit *Administer-&gt;Site configuration-&gt;Search settings* you will notice that the Views Fastsearch module has extended the options found on this page. There is now a *views\_fastsearch* fieldset at the bottom of the page with a field labeled *search\_index*. The issue here is the nature of the SQL query that gets built and an older bug with the search index building that leads to extra rows in the search\_index table. For a full discussion of the issue, see the [Drupal.org issue queue](http://drupal.org/node/143160). For those sites that started off life as Drupal 5.x sites, it is fairly safe to choose the *No duplicates (Unique Index Exists)* option and save the configuration. This will lead in the best performance for your fast searches.

   

   

 ![config.png](/sites/default/files/styles/wide_xs/public/assets/2016-04/config.png.webp?itok=ePM6rXc4 "config.png")

 *Figure XII: No duplicates (Unique Index Exists)*

## Other exciting stuff you can do

The Views Fastsearch filter is an exciting module that opens up many possibilities for custom searches in Drupal. One very neat feature is its exposing of a `hook_search_ranking` function. Modules can implement this function to add scoring factors to fast searches. For example, the Voting API could add a scoring factor that gave a higher score (and thus a higher ranking in search results) to content based on the average voting result. Since scoring factors can be weighed relative to each other, this gives administrators an amazing amount of control over the fine-tuning of search results.

Another neat trick that can be done with the fastsearch filter is to implement `theme_search_form` in such a way that the default search form is replaced with the filters from the fastsearch view. This effectively replaces core Drupal search with your fastsearch search.

 Published in:

- [  Drupal Site Building   ](/topics/drupal-site-building)

 

   You must have JavaScript enabled to use this form.

## Get in touch with us

### Tell us about your project. We'd love to hear from you!

 First Name  

 Last Name  

 Your email address  

 Your organization  

 How you heard about us  

 Tell us more 

     Leave this field blank