📄 searchcmd.cpp
字号:
//----------------------------------------------------------------------
// Search
//----------------------------------------------------------------------
//
//
//
// search [-i] [-v] [-d] [-h] [-g #] [-r # #] [help] indexname booleanquery [rankedquery]
//
// -i (optional) interactive search
// -v (optional) verbose mode (displays diagnostic info)
// -d (optional) display text stored in index for hit (required text stored)
// -h (optional) return # of hits
// -g # (optional) get a single hit
// -r # # (optional) get a range of hits (0 for last for all)
//
// help print help
// indexname the name of the index to be created or opened
// booleanquery the boolean part of the query
// rankedquery (optional) the ranked query
//
//
// A program to demonstrate querying an index. It assumes that the
// index was already created. The sample code to do this is in
// searchcmd.cpp. It is designed to be run from the command line,
// although it does check to see if it is being run from the IDE
// for testing.
//
// Notes: This uses the ranked version of Onix that also supports
// storing text in the index. This version has not yet been ported
// to all platforms and technically is beta software. It should be
// released shortly. Note that to display text you MUST have
// created an index that stores the text within the index.
//
// Hopefully this demo will help get started using Onix.
//
// History
// -------
// 11/6/00 CG Created from a modified version of test_search.cpp
// an old demo I'd created.
//
// 12/5/03 CG Updated it slightly in terms of scanning directories
// and also the API to correspond to various changes.
//--------------------------------------------------------------------
// The following is just a define I use so I can keep all my test and
// demo code in my project. I simply comment and uncomment the
// __RUN_NOW__ define to select which demo to run. I have several
// automated test programs that I use to check for various errors and
// this really speeds things up.
//#define __RUN_NOW__
#ifdef __RUN_NOW__
#include <stdio.h>
#include <ctype.h>
#include <string.h>
// This is the only include you need for Onix.
#include "onixapi.h"
// PASSCODES
// ---------
#define PASSCODE1 0xdf83ffae // Change these to the passcodes you were given as
#define PASSCODE2 0x4e782363 // part of your evaluation or the final codes.
// GLOBALS
// -------
OnixIndexManagerT theIndexManager; // the indexer object
StatusCodeT theStatus; // error status for Onix
// These are for the flags set at the command line
UCharT Display_Text; // Boolean - display stored text from index?
UCharT Verbose_Mode; // Boolean - print diagnostics?
UCharT Interactive_Mode; // Boolean - interactive queries?
UCharT Display_Hits; // Boolean - print number of hits
// Hits to display
int first_hit;
int last_hit;
// queries and index from command line
char rankedquery[255];
char booleanquery[255];
char IndexPath[255];
// readln
// ------
// Utility function to get around the annoying stdio features of the regular library.
// It reads in a line.
void readln( char *buf)
{ char c;
char *pos;
fflush( stdin );
pos = buf;
c = getc( stdin );
while ( c != '\n') {
*pos++ = c;
c = getc( stdin );
}
*pos = '\0';
}
// prepare_indexer
// ---------------
// Sets up the indexing object and opens up the index.
int prepare_indexer()
{
// The first thing we do is create an index object. This is used by all
// indexing functions and basically is the indexer itself.
theIndexManager = ixCreateIndexManager(PASSCODE1, PASSCODE2, &theStatus);
if ( theStatus < 0 ) {
printf( "\nError Creating Index Manager: %d \n", theStatus);
return -1;
}
// Before you can index you must first open an index file.
ixOpenIndex( theIndexManager, IndexPath, &theStatus );
if ( theStatus < 0 ) {
printf( "\nError Opening Index: %d \n", theStatus);
return -1;
}
// Start a session for performing queries
ixStartRetrievalSession( theIndexManager, &theStatus);
if ( theStatus < 0 ) {
printf( "\nError Starting Index Session: %d \n", theStatus);
return -1;
}
return 0;
}
// close_indexer
// -------------
// Closes down the indexing objects
int close_indexer()
{
ixEndRetrievalSession( theIndexManager, &theStatus);
if ( theStatus < 0 ) {
printf( "\nError Ending Index Session: %d \n", theStatus);
}
ixCloseIndex( theIndexManager, &theStatus);
if ( theStatus < 0 ) {
printf( "\nError Destroying Index Manager: %d \n", theStatus);
}
ixDeleteIndexManager(theIndexManager, &theStatus);
if ( theStatus < 0 ) {
printf( "\nError Destroying Index Manager: %d \n", theStatus);
}
return 0;
}
// display_record
// --------------
// Given a record number this will display it. Note that the index must have
// had the text stored within it for this to work! If it wasn't stored you'll
// probably just have the name of the file returned. (Given the way I wrote
// indexcmd.cpp)
int
display_record(int recnum)
{
char buffer[10000];
unsigned int datasize;
OnixDataCursorT DataCursor;
// Note that we create a maximum buffer of about 10K (9999 bytes) to be
// able to handle most text.
ixRetrieveRecordData( theIndexManager, (UCharT *) buffer, 9999, &datasize, recnum, &DataCursor, &theStatus);
if ( theStatus < 0 ) {
printf("Couldn't retrieve text! Was it stored in the index?\n");
return -1;
}
// Print the buffer by null terminating it and then printing it.
// Datasize is the size of the buffer. Note that we created a
// fairly large buffer so as to avoid buffer overruns.
buffer[ datasize ] = 0;
printf( buffer );
printf("\n");
printf("-----\n");
}
// process_hit
// -----------
// Given a vector and a hit number this will advance the vector (list of hits) to
// the given hit number and try to display as much information on that hit.
// (hit#, rec#, word#, ranking#, text)
int
process_hit( OnixQueryVectorT QueryVector, int hit )
{
int count;
RecordNumT recnum; // record hit
RecordNumT wordnum; // word hit
RecordNumT wordcount; // unused at present
FloatT weight; // ranking value for hit
// go to the beginning of the vector with the hits
ixVectorRewind( QueryVector, &theStatus );
// Go to the hit number specified by our parameter 'hit'
// Basically we just rewind the vector and go to the next
// vector count times.
for ( count = 1; count < hit; count++) {
ixVectorNextHit( QueryVector, &recnum, &wordnum, &wordcount, &weight, &theStatus);
if ( theStatus < 0 ) {
printf("\nError processing query vectors on hit %d.", count);
return -1;
}
}
// The above only works if the hit isn't the first hit.
// If it is we need to do the following instead
if ( hit == 1 ) {
ixVectorCurrentHit( QueryVector, &recnum, &wordnum, &wordcount, &weight, &theStatus);
if ( theStatus < 0 ) {
printf("\nError processing query vectors on hit %d.", count);
return -1;
}
}
// Display stats on hit
printf( "Hit: %d\n", hit );
printf( "Record: %d\n", recnum );
printf( "Word: %d\n", wordnum );
printf( "Weight: %f\n", weight);
printf("\n");
display_record( recnum );
}
// get_query
// ---------
// For interactive mode this prompts for a query. Onix allows the boolean query and
// the ranked query to be different. This allows you to do advanced processing on
// your ranking. i.e. boolean: "bill clinton" ranked: bill clinton will only
// find those hits that have the phrase bill clinton and then return those ranked
// properly. Using boolean: bill ranked: bill clinton is equivalent to saying
// that the query MUST have bill but includes clinton in the ranking. There are
// many advanced functions you can implement in this way. Note that the ranked
// query has NO operators in it - just words.
OnixQueryVectorT get_query()
{
char q_str[255]; // string holding query
char q_rhex[255]; // string holding query converted to hex
char q_bhex[255];
char buff[255];
OnixQueryVectorT vector;
// Technically all queries are in hex, so as to allow greater flexibility
// in dealing with foreign languages and specialized queries. This
// functions converts a regular query to a hex query.
printf("Enter Boolean part of Query (blank for no Boolean): \n:");
readln( buff );
printf("\n");
if ( strlen( buff ) >1 ) {
strcpy( q_str, buff );
printf("< %s >\n\n", q_str );
ixConvertQuery( (UCharT *) q_str, (UCharT *) q_bhex);
}
else {
q_str[0] = 0;
printf( "No Boolean query entered!\n");
return NULL;
}
printf("Enter Ranked part of Query (blank for no ranking): \n:");
readln( buff );
printf("\n");
if ( strlen( buff ) >1 ) {
strcpy( q_str, buff );
printf("< %s >\n\n", q_str );
ixConvertQuery( (UCharT *) q_str, (UCharT *) q_rhex);
vector = ixProcessQuery( theIndexManager, (UCharT *) q_rhex, (UCharT *) q_bhex, &theStatus );
}
else {
q_str[0] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -