📄 demo1.cpp
字号:
return 0;
}
// prepare_retrieval
// ----------------
//
// Sets up the indexing object and opens up the index. It is a little
// simpler than prepare_indexer as we don't have to worry about creating
// a new index. It depends upon the global IndexPath to determine the
// location of the index. (See the description of globals at the top of
// this file)
int prepare_retrieval()
{
// The first thing we do is create an index object. This is used by all
// retrieval functions and basically is the Onix object itself. Note that
// these passcodes are not the real ones and will not function.
StripControls( (char*) IndexPath );
// Before you can search an index you must first open the index file.
ixOpenIndex( theIndexManager, (char*) 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_retrieval
// --------------
//
// Closes down the indexing objects and ends our retrieval session.
int close_retrieval()
{
// Note that we have to be careful about the order we use.
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);
}
return 0;
}
//------------------------------------------------------------------------------------
// Search Functions
//------------------------------------------------------------------------------------
// 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 texts. This may not work for some text, but
// should be robust enough for this demo.
ixRetrieveRecordData( theIndexManager, (UCharT *) buffer, 9999, &datasize,
recnum, &DataCursor, &theStatus);
if ( theStatus < 0 ) {
printf("Couldn't retrieve text! Was it stored in the index?\n");
printf("Error: %d\n", theStatus );
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");
}
// 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 initial_hit )
{
int count;
int hit; // hit number
RecordNumT recnum; // record hit
RecordNumT wordnum; // word hit
RecordNumT wordcount; // unused at present
FloatT weight; // ranking value for hit
// The hit to start with is what was passed to us
hit = initial_hit;
while ( true ) {
// We could make this much more efficient, by checking to see if we
// really need to rewind and so forth. But we are fast enough that
// this doesn't add that much overhead and is a little clearer to
// demonstrate how you can step through the returned hits.
// Go to the hit number specified by our parameter 'hit'. Basically
// we just rewind the vector and go to the next vector count times.
ixVectorRewind( QueryVector, &theStatus );
if ( theStatus < 0 ) {
printf("\nError processing query vectors on hit %d.", count);
return -1;
}
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 and then the text of the hit itself. This assumes the
// text was stored in the index. If it wasn't then it'll display whatever was
// stored - usually the file path.
printf("---------------------------------------------------------------------------\n");
printf( "Hit: %d ", hit );
printf( "Record: %d ", recnum );
printf( "Word: %d ", wordnum );
if ( RQuery[0] != 0 ) {
printf( "Weight: %f", weight);
}
printf("\n\n");
display_record( recnum );
printf("---------------------------------------------------------------------------\n");
printf("(P)revious Record (N)ext Record (#) Specific Record (E)xit\n");
fgets( (char*) Choice, 10, stdin );
LowerString( Choice );
switch( Choice[0] ) {
case 'p':
// Previous
hit--;
if ( hit == 0 ) hit = 1;
break;
case 'n':
// Next - note that if we are at the last record this won't do much. But
// we leave that to Onix rather than keeping track of how many records
// were actually returned. You'll probably want to be a little cleaner
// in your own code.
hit++;
break;
case 'e':
pick = -1; // so we don't get accidentally thrown out of a loop
return 0;
break;
default:
// They typed in a number. Convert it to an integer and make that
// the new hit number
hit = atoi( Choice );
break;
}
} // while
}
// get_query
// ---------
//
// We pass into this function a "type" which is basically just the type of query.
// This type variable is really just the first letter of the selection you made
// in the search menu.
//
// This function then prompts for the 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.
OnixQueryVectorT get_query( char type )
{
char q_rhex[255]; // string holding ranked query converted to hex
char q_bhex[255]; // string holding boolean query converted to hex
// The following is a pointer to the memory containing the results of
// our query. We are responsible for freeing this memory. See the
// function "search" below for where we do this.
OnixQueryVectorT vector;
// Display some help information
// -----------------------------
printf( "SELECT QUERY\n");
printf( "------------\n");
printf( "\n");
if (( type == 'n' ) || ( type == 'c' )) {
printf( "Allowable Boolean Operators:\n");
printf( "\n");
printf( " & - and \"phrase\" - match exact phrase \n");
printf( " | - or * - match any number of characters \n");
printf( " ! - not ? - match any single character \n");
printf( " Note: regular expressions aren't \n");
printf( " allowed at the beginning of\n");
printf( " a word.\n");
printf( " w: # - within # words \n");
printf( "\n");
printf( "See http://www.lextek.com/manuals/onix/ixProcessQuery.htm\n");
printf( "for more information on query operators.\n");
printf( "\n\n");
}
if (( type == 'r') || ( type == 'c' )) {
printf( "Ranked queries are returned by order of significance\n");
printf( "Type the words you wish to search for. Not all words\n");
printf( "may actually be found in all returned records.\n");
printf( "Prepend a '-' to words you wish to exclude and a '+'\n");
printf( "to words you wish to require.\n");
printf( "\n\n");
}
// Get the query strings
// ---------------------
type = tolower( type ); // convert to lowercase
if (( type == 'n' ) || ( type == 'c' )) {
printf("Please enter your boolean query: \n");
fgets( (char*) Query, 255, stdin);
StripControls( (char*) Query );
ixConvertQuery( (UCharT *) Query, (UCharT *) q_bhex );
}
if (( type == 'r' ) || ( type == 'c' )) {
printf("Please enter your ranked query: \n");
fgets((char*) RQuery, 255, stdin);
StripControls( (char*) RQuery );
ixConvertQuery( (UCharT *) RQuery, (UCharT *) q_rhex);
}
// Process the Query
// -----------------
// The variable 'vector' is a global. (We put it there just so we knew
// where our main storage was)
if ( type == 'n' ) {
vector = ixProcessQuery( theIndexManager, (UCharT *) NULL, (UCharT *) q_bhex, &theStatus );
return vector;
}
if ( type == 'r' ) {
vector = ixProcessQuery( theIndexManager, (UCharT *) q_rhex, (UCharT *) NULL, &theStatus );
return vector;
}
if ( type == 'c' ) {
vector = ixProcessQuery( theIndexManager, (UCharT *) q_rhex, (UCharT *) q_bhex, &theStatus );
return vector;
}
return NULL;
}
// search
// ------
//
// Puts a menu allowing the user to search the index. Note that it first closes
// down the index. This may mean that the index is merged at this time. This
// may take some time, depending upon how much new data was added to the index.
int search()
{
ULongT hits = 0, records= 0, words = 0;
OnixQueryVectorT Results = NULL; // pointer to our storage
hits = 0;
records = 0;
printf("\n\n\n\n");
Results = NULL;
// Get stats about the number of records and hits for the query
if ( Results != NULL ) {
ixNumHits( Results, &hits, &records, &words, &theStatus);
}
if ( theStatus < 0 ) {
printf("\nError in Query\n");
return -1;
}
pick = -1; // we set this just so we don't prematurely exit the loop
while ( pick != 0 ) {
printf("Current Query: \n");
if ( Query[0] != 0 ) {
printf(" %s\n\n", Query);
} else {
printf(" No query selected\n");
}
if ( RQuery[0] != 0 ) {
if ( Query[0] != 0 ) {
printf( " Combined Query with %d Records and %d Hits\n", records, hits);
} else {
printf( " Ranked Query with %d Records and %d Hits\n", records, hits);
}
} else {
printf( " Regular Query with %d Records and %d Hits\n", records, hits);
}
printf( "\n");
printf( "(N) Search a new regular query\n");
printf( "(R) Search a new ranked query\n");
printf( "(C) Search a new combination of ranked and regular queries\n");
printf( "\n");
printf( " # Display Hit Number\n");
printf( "\n");
printf( "(E) Exit searching and return to Index menu\n");
printf( "\n\n");
fgets( (char*) Choice, 80, stdin);
switch ( Choice[0] ) {
case 'E':
case 'Q':
case 'e':
if ( Results != NULL ) {
// If we had a previous result we must free those results.
// We are always responsible for freeing memory returned by
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -