Querying

AddQuery

Prototype: function AddQuery ( $query, $index=“*“, $comment=”” )

Adds additional query with current settings to multi-query batch. $query is a query string. $index is an index name (or names) string. Additionally if provided, the contents of $comment are sent to the query log, marked in square brackets, just before the search terms, which can be very useful for debugging. Currently, this is limited to 128 characters. Returns index to results array returned from RunQueries.

Batch queries (or multi-queries) enable searchd to perform internal optimizations if possible. They also reduce network connection overheads and search process creation overheads in all cases. They do not result in any additional overheads compared to simple queries. Thus, if you run several different queries from your web page, you should always consider using multi-queries.

For instance, running the same full-text query but with different sorting or group-by settings will enable searchd to perform expensive full-text search and ranking operation only once, but compute multiple group-by results from its output.

This can be a big saver when you need to display not just plain search results but also some per-category counts, such as the amount of products grouped by vendor. Without multi-query, you would have to run several queries which perform essentially the same search and retrieve the same matches, but create result sets differently. With multi-query, you simply pass all these queries in a single batch and Manticore optimizes the redundant full-text search internally.

AddQuery() internally saves full current settings state along with the query, and you can safely change them afterwards for subsequent AddQuery() calls. Already added queries will not be affected; there’s actually no way to change them at all. Here’s an example:

$cl->SetSortMode ( SPH_SORT_RELEVANCE );
$cl->AddQuery ( "hello world", "documents" );

$cl->SetSortMode ( SPH_SORT_ATTR_DESC, "price" );
$cl->AddQuery ( "ipod", "products" );

$cl->AddQuery ( "harry potter", "books" );

$results = $cl->RunQueries ();

With the code above, 1st query will search for “hello world” in “documents” index and sort results by relevance, 2nd query will search for “ipod” in “products” index and sort results by price, and 3rd query will search for “harry potter” in “books” index while still sorting by price. Note that 2nd SetSortMode() call does not affect the first query (because it’s already added) but affects both other subsequent queries.

Additionally, any filters set up before an AddQuery() will fall through to subsequent queries. So, if SetFilter() is called before the first query, the same filter will be in place for the second (and subsequent) queries batched through AddQuery() unless you call ResetFilters() first. Alternatively, you can add additional filters as well.

This would also be true for grouping options and sorting options; no current sorting, filtering, and grouping settings are affected by this call; so subsequent queries will reuse current query settings.

AddQuery() returns an index into an array of results that will be returned from RunQueries() call. It is simply a sequentially increasing 0-based integer, ie. first call will return 0, second will return 1, and so on. Just a small helper so you won’t have to track the indexes manually if you need then.

Query

Prototype: function Query ( $query, $index=“*“, $comment=”” )

Connects to searchd server, runs given search query with current settings, obtains and returns the result set.

$query is a query string. $index is an index name (or names) string. Returns false and sets GetLastError() message on general error. Returns search result set on success. Additionally, the contents of $comment are sent to the query log, marked in square brackets, just before the search terms, which can be very useful for debugging. Currently, the comment is limited to 128 characters.

Default value for $index is "*" that means to query all local indexes. Characters allowed in index names include Latin letters (a-z), numbers (0-9) and underscore (_); everything else is considered a separator. Note that index name should not start with underscore character. Therefore, all of the following samples calls are valid and will search the same two indexes:

$cl->Query ( "test query", "main delta" );
$cl->Query ( "test query", "main;delta" );
$cl->Query ( "test query", "main, delta" );

Index specification order matters. If document with identical IDs are found in two or more indexes, weight and attribute values from the very last matching index will be used for sorting and returning to client (unless explicitly overridden with SetIndexWeights()). Therefore, in the example above, matches from “delta” index will always win over matches from “main”.

On success, Query() returns a result set that contains some of the found matches (as requested by SetLimits()) and additional general per-query statistics. The result set is a hash (PHP specific; other languages might utilize other structures instead of hash) with the following keys and values:

  • “matches”:
  • Hash which maps found document IDs to another small hash containing document weight and attribute values (or an array of the similar small hashes if SetArrayResult() was enabled).
  • “total”:
  • Total amount of matches retrieved on server (ie. to the server side result set) by this query. You can retrieve up to this amount of matches from server for this query text with current query settings.
  • “total_found”:
  • Total amount of matching documents in index (that were found and processed on server).
  • “words”:
  • Hash which maps query keywords (case-folded, stemmed, and otherwise processed) to a small hash with per-keyword statistics (“docs”, “hits”).
  • “error”:
  • Query error message reported by searchd (string, human readable). Empty if there were no errors.
  • “warning”:
  • Query warning message reported by searchd (string, human readable). Empty if there were no warnings.

It should be noted that Query() carries out the same actions as AddQuery() and RunQueries() without the intermediate steps; it is analogous to a single AddQuery() call, followed by a corresponding RunQueries(), then returning the first array element of matches (from the first, and only, query.)

RunQueries

Prototype: function RunQueries ()

Connect to searchd, runs a batch of all queries added using AddQuery(), obtains and returns the result sets. Returns false and sets GetLastError() message on general error (such as network I/O failure). Returns a plain array of result sets on success.

Each result set in the returned array is exactly the same as the result set returned from Query.

Note that the batch query request itself almost always succeeds - unless there’s a network error, blocking index rotation in progress, or another general failure which prevents the whole request from being processed.

However individual queries within the batch might very well fail. In this case their respective result sets will contain non-empty "error" message, but no matches or query statistics. In the extreme case all queries within the batch could fail. There still will be no general error reported, because API was able to successfully connect to searchd, submit the batch, and receive the results - but every result set will have a specific error message.

ResetFilters

Prototype: function ResetFilters ()

Clears all currently set filters.

This call is only normally required when using multi-queries. You might want to set different filters for different queries in the batch. To do that, you should call ResetFilters() and add new filters using the respective calls.

ResetGroupBy

Prototype: function ResetGroupBy ()

Clears all currently group-by settings, and disables group-by.

This call is only normally required when using multi-queries. You can change individual group-by settings using SetGroupBy() and SetGroupDistinct() calls, but you can not disable group-by using those calls. ResetGroupBy() fully resets previous group-by settings and disables group-by mode in the current state, so that subsequent AddQuery() calls can perform non-grouping searches.