For more information... RTFM!
NAVIGATION
PAGES THAT LINK HERE
ACCOUNT LOGIN

You are not logged in

Powered by Interchange version 5.7.0

Interchange search engine

Introduction

Interchange implements a search engine which will search the DefaultTables, or any other table, for items based upon user input.  It uses either forms or link-based searches which are invoked using the "scan" ActionMap.  The search engine provides several Interchange tags and makes use of many variables.

If the search is implemented in a link or in a form, it will always display formatted results on a separate results page, which is an Interchange page that uses some combination of the [search-region] tag, along with the [search-list], [more-list], [more] and other sub-tags, to format and display the results.

A full list of one-click search variables, and their two-letter abbreviations, can be found on the Search parameters page.

The search form

A number of <form> variables can be defined to determine which type of search will be used, which columns in a table should be searched and what the search behaviour should be.

Here is a simple search form:

<form action="[area search]" method="POST">
    <input type="text" size="30" name="mv_searchspec">
    <input type="submit" value="Search">
</form>

When the "Search" button is pressed, Interchange will search the DefaultTables table(s) for the string entered into the "mv_searchspec" text field, and will make the results available for display on a results page.

The same search for a fixed string ("shirt", for instance) could be performed with the use of a hot link, using the special "scan" URI.  For example:

<a href="[area search='se=shirt']">See our shirt collection</a>

This mechanism is referred to as a one-click search in this documentation.

The default is to search every column in the table.  To restrict the search to a "description" column, the search specification, in the above form, could be modified to add the following:

<input type="hidden" name="mv_search_field" value="description">

Or, in a one-click search:

<a href="[area search=|
    se=shirt
    sf=description
|]"
>
See our shirt collection</a>

You could use checkboxes or radio button fields to let the user decide on the search parameters, as follows:

<input type="checkbox" name="mv_search_field" value="author"> Search by author <br>
<input type="checkbox" name="mv_search_field" value="title"> Search by title <br>

Search specifications can be stacked.  If more than one checkbox is checked then all of the selected columns will be searched.

Coordinated and joined searches

Interchange can perform a complete range of tests on individual columns in the target table.  To use this function, set "mv_coordinate" to "Yes" (or "co=yes" in the one-click syntax).  In order to use coordinated searching, the number of search fields must equal the number of search strings.

To make sure that is the case, you can use the "mv_search_map" variable, which allows variables to be mapped to others in the search specification.  For example:

<input type="hidden" name="mv_search_map" value="
    mv_searchspec=search1
    mv_searchspec=search2
    mv_searchspec=search3
"
>
<input type="hidden" name="mv_search_field" value="title">
<input type="hidden" name="mv_search_field" value="artist">
<input type="hidden" name="mv_search_field" value="category">

Artist: <input name="search1" value=""><br>
Title:  <input name="search2" value=""><br>
Genre:  <input name="search3" value=""><br>

The search will work even if the user leaves one of the input fields blank.

Leading/trailing whitespace is stripped from all lines in the "mv_search_map" variable, so it can be positioned as shown for convenience.

Coordinated searches may be joined with the output of another table if one of the "mv_search_field" values is set to a "table:column" pair.

Note

Note

Table joins will slow down large searches considerably unless there is another search specification, as the second table must be accessed for every row resulting from a search of the primary table.

If there is a search field that qualifies for a regular expression search function, or you are conducting a binary search with mv_dict_look, or are not doing an or search, the penalty should not be too great, as only matching rows will trigger a table lookup.

Individual column operations can be specified with the "mv_column_op" (aka "op") parameter.  The operations include the following:

Name String column Numeric column Alternative operator
Equal to eq == =
Not equal to ne != <>
Greater than gt >  
Less than lt <  
Less than/equal to le <=  
Greater than/equal to ge >=  
Regular expression (match) rm =~
Regular expression (not) rn !~
Exact match em    
Text::Query::Advanced aq    
Text::Query::Simple tq    

The special "aq" and "tq" query operators only work if the

Text::Query Link to an external page Perl module is installed.  This allows Altavista-style searches on columns, using "AND", "OR", "NOT" and "NEAR", with arbitrarily complex parentheses.

A useful search form, using the "aq" operator, could be written as follows:

<form action="[area search]" method="POST">
    <input type="hidden name="mv_session_id" value="[data session id]">

    <input type="
hidden" name="mv_searchtype" value="db">
    <input type="
hidden" name="mv_coordinate" value="1">
    <input type="
hidden" name="mv_min_string" value="2">

    <input type="
hidden" name="mv_column_op" value="aq">
    <input type="
hidden" name="mv_search_field" value=":sku:description:comment:category">
    <input name="
mv_searchspec" type="text" size="20">

    <input type="
submit" value="Search">
</form>

This searches the "sku", "description", "comment" and "category" columns in the DefaultTables table(s) using the

Text::Query Link to an external page syntax.  A valid search string could be "painters NEAR set".

Single table coordinated search example

<a href="[area search=|
    co=yes

    sf=title
    se=Sunflowers
    op=em

    sf=artist
    se=Van Gogh
    op=rm
|]">Sunflowers by Van Gogh</a>

Multiple table (joined) coordinated search examples

<a href="[area search=|
    co=yes

    sf=title
    se=Sunflowers
    nu=0
    op=!~

    sf=artist
    se=Van Gogh
    op=rm
    nu=0

    sf=inventory:quantity
    se=1
    op=>=
    nu=1
|]">Any in stock except Sunflowers by Van Gogh</a>

Note that, "nu=0" must be specified in the joined search example, even though that is the default.  To avoid having to do this, use the attribute array feature.  For example:

<a href="[area search.0=|
    sf=title
    se=Sunflowers
    op=!~
|
search.1=|
    sf=artist
    se=Van Gogh
|
search.2=|
    sf=inventory:quantity
    se=1
    op=>=
    nu=1
|]">Any in stock except Sunflowers by Van Gogh</a>

The "co=yes" is assumed when using an attribute array to create a search specification.

The multiple table search will check the product's stock status, provided there is an "inventory" table with a "quantity" column, as there is in the Interchange Standard ecommerce demo.  If the "inventory" table's "quantity" column is numerically greater than or equal to 1 then the product will be selected, otherwise the product will be deemed to be out of stock and therefore not selected.  The tables will be joined using their KEY column.

It always helps to have a "rm" type included in the search.  This is used to pre-screen rows so that joining-table accesses only need be made for already-matching entries.  If accesses must be made for every row, large searches could be quite slow.

Custom search operators (using SearchOp)

You can write your own search operator (known as a SearchOp) with Interchange's CodeDef configuration directive.  For example:

CodeDef  eq_nopunc  SearchOp
CodeDef  eq_nopunc  Routine  <<EOR
sub {
    my ($self,$i,$pat) = @_;
    $pat =~ s/[^A-Za-z0-9]//g;
    $pat = qr/$pat/i;

    return sub {
        my $string = shift;
        $string =~ s/[^A-Za-z0-9]//g;
        return $string =~ $pat;
    };
}
EOR

The above custom operator would match "O'Reily" if the user searched for "oreily", and "12-34-56-78" if the user searched for "1234-5678" etc.

The parameters passed to the custom code are as follows:

  1. The search object ($self).
  2. The index into the coordinated search array ($i).
  3. The pattern to match.
  4. The name of the operator ("eq_nopunc", in this case).

The CodeDef routine must return a reference to a Perl subroutine.  The subroutine will be passed the string to match against, and must return true if a match is found, or false if no match is found.

Note

Note

Custom search operators do not honour the "mv_negate" specification unless you code them to do so.

With the above, you can do this:

[loop search=|
    se=sretniap
    sf=description
    fi=products
    st=db
    co=yes
    rf=*
    op=find_mirrored
|]
    [loop-code] = [loop-param description]<br>
[/loop]

See Vend::Search::create_text_query(), in the Interchange source code, for an example of how to return a subroutine that can look into the search object for the associated search specification.

Specifying a search with SQL-style syntax

SQL syntax can be specified for Interchange searches.  This is not the same as the external SQL database server search, treated separately below.  The SQL-like syntax will act as a filter on the results of a select everything table dump, rather than being sent directly to the SQL server.

This syntax allows this form setup:

Artist: <input name="artist">
Title:  <input name="title">
<input type="hidden" name="mv_sql_query" value="
    SELECT  code
    FROM    products
    WHERE   artist LIKE artist
    AND     title LIKE title
"
>

If the right hand side of an expression looks like a column (it is not quoted), then the appropriate form variable is substituted.  If used in a one-click, the corresponding scratchpad variable is used instead.  The assumption is reversed for the left-hand side;  If it is a quoted string then the column name is read from the passed values.  Otherwise, the column name is taken literally.

Search for: <input name="searchstring"><br>
Search in<input type="radio" name="column" value="title"> title

<input type="radio" name="column" value="artist"> artist
<input type="hidden" name="mv_sql_query" value="
    SELECT  code
    FROM    products
    WHERE   'column' LIKE searchstring
">

Once again, the query is not sent to the SQL server directly.  Parentheses will have no effect, and "AND" and "OR" conditions will cause all conditions to be "OR".  The searches above would be similar to the following:

[area search=|
    co=yes
    sf=artist
    op=rm
    se=[value artist]
    sf=title
    op=rm
    se=[value title]
|]">Search for [value artist], [value title]</a>
<a href="[area search=|
    co=yes
    sf=[value column]
    op=rm
    se=[value searchstring]
|]"> Search for [value searchstring] in [value column] </a>

One-click searches

Interchange allows a search to be passed in a URI, as described above.  The earlier examples looked a little like this:

<a href="[area search=|
    se=Impressionists
    sf=category
|]"
>
Impressionist Paintings </a>

This is another way to do the same thing:

<a href="[area scan se=Impressionists/sf=category]"> Impressionist Paintings </a>

Assuming your VendURL is "www.example.com/cgi-bin/vlink", those links would translate to the following:

<a href="http://www.example.com/cgi-bin/vlink/scan/se=Impressionists/sf=category"> Impressionist Paintings </a>

Each of the search specification variables long name and an abbreviated name.  For example, both "mv_searchspec" and "se" are equivalent.  The abbreviations help to keep the length of one-click search URIs down, while the full names are easier to read in HTML forms.

Note

Note

A full list of search variables, and their two-letter abbreviations, can be found on the Search parameters page.

A one-click search may be specified in three different ways, as follows:

Original syntax

If you want to create an "OR" search URI on the category and artist columns, for the strings "Surreal" and "Gogh", while matching substrings, you could do the following:

[area scan se=Surreal/se=Gogh/os=yes/su=yes/sf=artist/sf=category]

In this method of specification, to replace a slash (/) in a file name (for the sp, bd or fi parameters etc.) you must use the shorthand of ::  (i.e. sp=results::standard).  This may not work for some browsers, so you should probably either put the page in the main pages directory or define the page in a search profile instead.

Ampersand syntax

You can substitute & for / in the specification, and then be able to use / and quotes and spaces in the specification.  For example:

[area scan se="Van Gogh"&sp=lists/surreal&os=yes&su=yes&sf=artist&sf=category]

Any "unsafe" characters on the resulting URI will be escaped.

Multi-line syntax

You can specify parameters one per line, if you prefer, as follows:

[area scan
    se="Van Gogh"
    sp=lists/surreal
    os=yes
    su=yes
    sf=artist
    sf=category
]

Again, any "unsafe" characters in the resulting URI will be escaped.  You may not search for trailing spaces using this method.

Joined Searches

You can create a joined search using a parameter array.

[area href=scan
    search.0=|
        se=fragrant
        fi=products
        sf=smell
    |
    search.1=|
        se=purple
        sf=color
    |
    search.2=|
        se=perennial
        sf=type
    |
]

The search routine called by the [area] tag automatically adds the other relevant search specification elements, including the "co=yes" to indicate a combined search, as appropriate.

Setting display options with mv_value

You can encode an arbitrary value into the search URI, without having to use URI arguments, by making use of the "mv_value" search parameter.  The "mv_value" search specification takes an argument of "var=value".

Actually "mv_value" is a misnomer, as it will almost never be used in a <form> where variable values can be set.  It's a lot more useful in a One-click search.

For example, the following will set a variable that can be displayed on the search results page using [value category_name]:

<a href="[area href=scan arg=|
    se=Renaissance
    se=Impressionists
    va=category_name=Renaissance and Impressionist Paintings
|]"
>
Renaissance and Impressionist Paintings</a>

In-page searches

As well as creating search links and forms, you may also create a search from within a page, and display the results of that search on the same page.

The [loop] tag accepts search parameters and allows you to loop through the results, using [PREFIX-*] tags to display the results.  For example, to search for all products in the "Americana" and "Contemporary" categories:

[loop search=|
    se=Americana
    se=Contemporary
    os=yes
    sf=category9
|]
    Artist: [loop-field artist]<BR>
    Title: [loop-field title]<P>
[/loop]

Search parameters are the same as for One-click searches, above.

The advantage of the in-page search is that searches can be embedded within searches, and you can use an ordinary-looking HTML link to get to the page from any external website.

To place an in-page search with the full range of display in a normal results page, you can use the [search-region] tag.  This works in the same way as the [loop] tag, above, except that sub-tags such as [search-list], [more-list] and [more] can be placed within the tag's results template.  For example:

[search-region
    more=1
    search=|
        se=Americana
        sf=category
        ml=2
|]
[search-list]
    <p>
        <a href="[area href='[item-code]']">[item-field title]</a>
        by [item-field artist]<br>
        [item-description]
    </p>
[/search-list]

[no-match]
Sorry, no matches for [value mv_searchspec].
[/no-match]

[more-list]
    Results [matches] of [match-count] shown<br>
    [more]
[/more-list]
[/search-region]

Search profiles

An unlimited number of search profiles can be predefined that either reside in scratchpad variables, or in files declared using the SearchProfile local configuration directive.

A search profile can be created in a scratchpad variable, as follows:

[set artist_profile]
mv_search_field=artist
mv_search_field=category
mv_orsearch=yes
[/set]

You can make use of the search profile by using the following, instead of a full search specification, on your search <form>:

<input type="hidden" name="mv_profile" value="artist_profile">

or use the "mp" modifier in a one-click search, as follows:

<a href="[area scan se=Leonardo/mp=artist_profile]"> A left-handed artist </a>

As well as (or instead of) using scratchpad variables, you can use the [SearchProfile] directive to name files that will hold search profiles.

The search profile is named by placing a name after a __NAME__ token, in one of the listed profile files.  Multiple profiles can reside in the same file, if separated by __END__ tokens.

As an added measure of control, the specification is evaluated with the Interchange tag syntax to provide conditional setting of search parameters.

The special "mv_last" variable stops interpretation of any further search variables in the current profile, except for the "mv_dict_look" and "mv_searchspec" variables, which are interpreted in any event.

Category:  Interchange database
Last modified by: Kevin Walsh
Modification date: Wednesday 19 September 2007 at 4:53 PM (EDT)
Home  |  Legal nonsense  |  Privacy policy  |  Donations  |  Contact us