Changeset 27064

Show
Ignore:
Timestamp:
12.03.2013 14:37:44 (7 years ago)
Author:
kjdon
Message:

adding reverse sort/sort order in for lucene search results sorting. reorganising code to avoid duplication, added fieldedqueryfilter in the chain of inheritance

Location:
main/trunk/greenstone2/runtime-src/src/colservr
Files:
2 added
8 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone2/runtime-src/src/colservr/lucenequeryfilter.cpp

    r22050 r27064  
    2828#include "lucenesearch.h" 
    2929 
    30 ///////////////////////////////// 
    31 // functions for queryfilterclass 
    32 ///////////////////////////////// 
    33  
    34  
    3530lucenequeryfilterclass::lucenequeryfilterclass ()  
    36   : queryfilterclass() { 
     31  : fieldedqueryfilterclass() { 
    3732 
    3833   
    3934  FilterOption_t filtopt; 
    4035   
    41   // -- onePerTerm  Level          enumerated 
    42   // likely to be Doc, Sec, Para, but we dont assume anything now 
     36  // -- onePerQuery SortField, enumerated, used to list available sorting fields 
    4337  filtopt.clear(); 
    44   filtopt.name = "Level"; 
     38  filtopt.name = "SortField"; 
    4539  filtopt.type = FilterOption_t::enumeratedt; 
    46   filtopt.repeatable = FilterOption_t::onePerTerm; 
     40  filtopt.repeatable = FilterOption_t::onePerQuery; 
    4741  filtopt.defaultValue = ""; 
    48   filterOptions["Level"] = filtopt; 
    49  
    50   // --  IndexField, enumerated, used to list available fields 
     42  filterOptions["SortField"] = filtopt; 
     43 
     44  // -- onePerQuery SortOder      enumerated (0=ascending, 1=descending) 
    5145  filtopt.clear(); 
    52   filtopt.name = "IndexField"; 
     46  filtopt.name = "SortOrder"; 
    5347  filtopt.type = FilterOption_t::enumeratedt; 
    54   filtopt.repeatable = FilterOption_t::onePerTerm; 
     48  filtopt.repeatable = FilterOption_t::onePerQuery; 
     49  filtopt.defaultValue = "ascending"; 
     50  filtopt.validValues.push_back("ascending"); 
     51  filtopt.validValues.push_back("descending"); 
     52  filterOptions["SortOrder"] = filtopt; 
     53 
     54  // -- onePerQuery Fuzziness string 0.0-1.0 
     55  filtopt.clear(); 
     56  filtopt.name = "Fuzziness"; 
     57  filtopt.type = FilterOption_t::stringt; 
     58  filtopt.repeatable = FilterOption_t::onePerQuery; 
    5559  filtopt.defaultValue = ""; 
    56   filterOptions["IndexField"] = filtopt; 
    57  
     60  filterOptions["Fuzziness"] = filtopt; 
     61 
     62 // -- onePerQuery FilterString  string 
     63  filtopt.clear(); 
     64  filtopt.name = "FilterString"; 
     65  filtopt.type = FilterOption_t::stringt; 
     66  filtopt.repeatable = FilterOption_t::onePerQuery; 
     67  filtopt.defaultValue = ""; 
     68  filterOptions["FilterString"] = filtopt; 
    5869} 
    5970 
     
    6273 
    6374 
    64 //whether a query is a full text browse 
    65 bool lucenequeryfilterclass::full_text_browse (int filterRequestOptions) { 
    66   return (filterRequestOptions & FRfullTextBrowse); 
    67 } 
    6875 
    6976void lucenequeryfilterclass::configure (const text_t &key, const text_tarray &cfgline) { 
    70   queryfilterclass::configure(key, cfgline); 
    71  
    72   if (key == "indexfieldmap") { 
    73     indexfieldmap.importmap (cfgline); 
    74      
    75     // update the list of indexes in the filter information 
    76     text_tarray options; 
    77     indexfieldmap.gettoarray (options); 
    78     filterOptions["IndexField"].validValues = options; 
    79   } else if (key == "levelmap") { 
    80     levelmap.importmap (cfgline); 
    81   } else if (key == "indexlevels") { 
    82     text_tarray::const_iterator here = cfgline.begin(); 
    83     text_tarray::const_iterator end = cfgline.end(); 
    84     while (here != end) { 
    85       if (!(*here).empty()) { 
    86     filterOptions["Level"].validValues.push_back(*here); 
    87       } 
    88       ++here; 
    89     } 
    90   } else if (key == "textlevel") { 
    91       ((lucenesearchclass *)textsearchptr)->set_text_level(cfgline[0]); 
    92   } else if (key == "defaultindex") {  
    93     indexfieldmap.from2to (cfgline[0], filterOptions["IndexField"].defaultValue); 
    94   } else if (key == "defaultlevel") {  
    95     levelmap.from2to (cfgline[0], filterOptions["Level"].defaultValue); 
    96   } 
    97    
     77  fieldedqueryfilterclass::configure(key, cfgline); 
     78 
     79  if (key == "textlevel") { 
     80    ((lucenesearchclass *)textsearchptr)->set_text_level(cfgline[0]); 
     81  } 
    9882} 
    9983 
    10084bool lucenequeryfilterclass::init (ostream &logout) { 
    10185   
    102   if (!queryfilterclass::init(logout)) { 
     86  if (!fieldedqueryfilterclass::init(logout)) { 
    10387    return false; 
    10488  } 
    10589   
    106   if (filterOptions["IndexField"].defaultValue.empty()) { 
    107     // use first index in map as default if no default is set explicitly 
    108     text_tarray fromarray; 
    109     indexfieldmap.getfromarray(fromarray); 
    110     if (fromarray.size()) { 
    111       filterOptions["IndexField"].defaultValue = fromarray[0]; 
    112     } 
    113   } 
    114   if (filterOptions["Levels"].defaultValue.empty()) { 
    115     // use first level as default if no default is set explicitly 
    116     if (!filterOptions["Level"].validValues[0].empty()) 
    117       filterOptions["Levels"].defaultValue = filterOptions["Level"].validValues[0]; 
    118   } 
    119  
     90  text_tarray field_array; 
     91  indexfieldmap.gettoarray(field_array); 
     92  for (int i=0; i<field_array.size(); i++) { 
     93    text_t field = field_array[i]; 
     94    if (field!="ZZ" && field !="ZZ") { 
     95      filterOptions["SortField"].validValues.push_back("by"+field); 
     96    } 
     97  } 
    12098  return true; 
    12199} 
     100 
     101void lucenequeryfilterclass::set_queryparam_defaults(queryparamclass &query ) { 
     102 
     103  fieldedqueryfilterclass::set_queryparam_defaults(query); 
     104  query.filterstring = filterOptions["FilterString"].defaultValue;   
     105  query.sortfield = filterOptions["SortField"].defaultValue; 
     106  query.sortorder = (filterOptions["SortOrder"].defaultValue == "descending"); 
     107  query.fuzziness = filterOptions["Fuzziness"].defaultValue;   
     108 
     109} 
     110 
    122111 
    123112void lucenequeryfilterclass::filter(const FilterRequest_t &request, 
     
    160149  // get the query parameters 
    161150  int startresults, endresults; 
    162   text_t phrasematch; // not used here any more 
    163151  vector<queryparamclass> queryfilterparams; 
    164152  parse_query_params (request, queryfilterparams, startresults,  
    165               endresults, phrasematch, logout);   
     153              endresults, logout);   
    166154  
    167155    
     
    258246  // get the query parameters 
    259247  int startresults, endresults; 
    260   text_t phrasematch; // not used here any more, just have it so can use 
    261                       // parse_query_params function 
    262248   
    263249  vector<queryparamclass> queryfilterparams; 
    264250  parse_query_params (request, queryfilterparams, startresults,  
    265               endresults, phrasematch, logout);   
     251              endresults, logout);   
    266252 
    267253  vector<queryparamclass>::const_iterator query_here = queryfilterparams.begin(); 
     
    392378 
    393379 
    394  
  • main/trunk/greenstone2/runtime-src/src/colservr/lucenequeryfilter.h

    r20727 r27064  
    3030#define LUCENEQUERYFILTER_H 
    3131 
    32 #include "queryfilter.h" 
     32#include "fieldedqueryfilter.h" 
    3333 
    34 class lucenequeryfilterclass : public queryfilterclass { 
     34class lucenequeryfilterclass : public fieldedqueryfilterclass { 
    3535protected: 
    3636 
    37   stringmap indexfieldmap; 
    38   stringmap levelmap; 
    39  
    40   bool full_text_browse (int filterRequestOptions); 
    4137 
    4238  // mgsearchptr and db_ptr are assumed to be valid 
     
    4642               comerror_t &err, ostream &logout); 
    4743 
     44  void set_queryparam_defaults(queryparamclass &query ); 
    4845 
    4946public: 
  • main/trunk/greenstone2/runtime-src/src/colservr/mgppqueryfilter.cpp

    r20727 r27064  
    11/********************************************************************** 
    22 * 
    3  * queryfilter.cpp --  
     3 * mgppqueryfilter.cpp --  
    44 * Copyright (C) 1999  The New Zealand Digital Library Project 
    55 * 
     
    2828#include "mgppsearch.h" 
    2929 
    30 ///////////////////////////////// 
    31 // functions for queryfilterclass 
    32 ///////////////////////////////// 
    33  
    34  
    3530mgppqueryfilterclass::mgppqueryfilterclass ()  
    36   : queryfilterclass() { 
    37  
    38    
    39   FilterOption_t filtopt; 
    40    
    41   // -- onePerTerm  Level          enumerated 
    42   // likely to be Doc, Sec, Para, but we dont assume anything now 
    43   filtopt.clear(); 
    44   filtopt.name = "Level"; 
    45   filtopt.type = FilterOption_t::enumeratedt; 
    46   filtopt.repeatable = FilterOption_t::onePerTerm; 
    47   filtopt.defaultValue = ""; 
    48   filterOptions["Level"] = filtopt; 
    49  
    50   // --  IndexField, enumerated, used to list available fields 
    51   filtopt.clear(); 
    52   filtopt.name = "IndexField"; 
    53   filtopt.type = FilterOption_t::enumeratedt; 
    54   filtopt.repeatable = FilterOption_t::onePerTerm; 
    55   filtopt.defaultValue = ""; 
    56   filterOptions["IndexField"] = filtopt; 
     31  : fieldedqueryfilterclass() { 
    5732 
    5833} 
     
    6237 
    6338 
    64 //whether a query is a full text browse 
    65 bool mgppqueryfilterclass::full_text_browse (int filterRequestOptions) { 
    66   return (filterRequestOptions & FRfullTextBrowse); 
    67 } 
    6839 
    6940void mgppqueryfilterclass::configure (const text_t &key, const text_tarray &cfgline) { 
    70   queryfilterclass::configure(key, cfgline); 
    71  
    72   if (key == "indexfieldmap") { 
    73     indexfieldmap.importmap (cfgline); 
    74     text_tarray options; 
    75     indexfieldmap.gettoarray (options); 
    76     filterOptions["IndexField"].validValues = options; 
    77      
    78   } else if (key == "levelmap") { 
    79     levelmap.importmap (cfgline); 
    80   } else if (key == "indexlevels") { 
    81     filterOptions["Level"].validValues.erase(filterOptions["Level"].validValues.begin(), filterOptions["Level"].validValues.end()); 
    82     text_tarray::const_iterator here = cfgline.begin(); 
    83     text_tarray::const_iterator end = cfgline.end(); 
    84     while (here != end) { 
    85       if (!(*here).empty()) { 
    86     filterOptions["Level"].validValues.push_back(*here); 
    87       } 
    88       ++here; 
    89     } 
    90   } else if (key == "textlevel") { 
    91       ((mgppsearchclass *)textsearchptr)->set_text_level(cfgline[0]); 
     41  fieldedqueryfilterclass::configure(key, cfgline); 
     42 
     43  if (key == "textlevel") { 
     44    ((mgppsearchclass *)textsearchptr)->set_text_level(cfgline[0]); 
    9245  } else if (key == "indexstem") { 
    9346    ((mgppsearchclass *)textsearchptr)->set_indexstem (cfgline[0]); 
    94   } else if (key == "defaultindex") { // used for fields in mgpp 
    95     indexfieldmap.from2to (cfgline[0], filterOptions["IndexField"].defaultValue); 
    96   } else if (key == "defaultlevel") {  
    97     levelmap.from2to (cfgline[0], filterOptions["Level"].defaultValue); 
    98   } 
    99    
    100 } 
    101  
    102 bool mgppqueryfilterclass::init (ostream &logout) { 
    103    
    104   if (!queryfilterclass::init(logout)) { 
    105     return false; 
    106   } 
    107    
    108   if (filterOptions["IndexField"].defaultValue.empty()) { 
    109     // use first index in map as default if no default is set explicitly 
    110     text_tarray fromarray; 
    111     indexfieldmap.getfromarray(fromarray); 
    112     if (fromarray.size()) { 
    113       filterOptions["IndexField"].defaultValue = fromarray[0]; 
    114     } 
    115   } 
    116   if (filterOptions["Levels"].defaultValue.empty()) { 
    117     // use first level as default if no default is set explicitly 
    118     if (!filterOptions["Level"].validValues[0].empty()) 
    119       filterOptions["Levels"].defaultValue = filterOptions["Level"].validValues[0]; 
    120   } 
    121  
    122   return true; 
     47  } 
    12348} 
    12449 
     
    16388  // get the query parameters 
    16489  int startresults, endresults; 
    165   text_t phrasematch; // not used here any more 
    16690  vector<queryparamclass> queryfilterparams; 
    16791  parse_query_params (request, queryfilterparams, startresults,  
    168               endresults, phrasematch, logout);   
     92              endresults, logout);   
    16993  
    17094    
     
    261185  // get the query parameters 
    262186  int startresults, endresults; 
    263   text_t phrasematch; // not used here any more, just have it so can use 
    264                       // parse_query_params function 
    265    
    266187  vector<queryparamclass> queryfilterparams; 
    267188  parse_query_params (request, queryfilterparams, startresults,  
    268               endresults, phrasematch, logout);   
     189              endresults, logout);   
    269190 
    270191    vector<queryparamclass>::const_iterator query_here = queryfilterparams.begin(); 
  • main/trunk/greenstone2/runtime-src/src/colservr/mgppqueryfilter.h

    r20727 r27064  
    2929#define MGPPQUERYFILTER_H 
    3030 
    31 #include "queryfilter.h" 
     31#include "fieldedqueryfilter.h" 
    3232 
    3333 
    34 class mgppqueryfilterclass : public queryfilterclass { 
     34class mgppqueryfilterclass : public fieldedqueryfilterclass { 
    3535protected: 
    3636 
    37   stringmap indexfieldmap; 
    38   stringmap levelmap; 
    39  
    40   bool full_text_browse (int filterRequestOptions); 
    4137 
    4238  // textsearchptr and db_ptr are assumed to be valid 
     
    5248 
    5349  void configure (const text_t &key, const text_tarray &cfgline); 
    54   bool init (ostream &logout); 
     50  //  bool init (ostream &logout); 
    5551  void filter (const FilterRequest_t &request, 
    5652               FilterResponse_t &response, 
  • main/trunk/greenstone2/runtime-src/src/colservr/mgqueryfilter.cpp

    r16445 r27064  
    285285 
    286286  num_phrases = 0; 
     287 
     288  FilterOption_t filtopt; 
     289  // -- onePerQuery  PhraseMatch  enumerated 
     290  filtopt.name = "PhraseMatch"; 
     291  filtopt.type = FilterOption_t::enumeratedt; 
     292  filtopt.repeatable = FilterOption_t::onePerQuery; 
     293  filtopt.defaultValue = "some_phrases"; 
     294  filtopt.validValues.push_back ("all_phrases"); 
     295  filtopt.validValues.push_back ("some_phrases"); 
     296  filtopt.validValues.push_back ("all_docs"); 
     297  filterOptions["PhraseMatch"] = filtopt; 
     298 
    287299} 
    288300 
     
    331343              endresults, phrasematch, logout); 
    332344  // do any mg specific diddling with query parameters that may be required 
    333   mg_parse_query_params (request, queryfilterparams, startresults,  
    334              endresults, phrasematch, logout); 
     345  //  mg_parse_query_params (request, queryfilterparams, startresults,  
     346  //             endresults, phrasematch, logout); 
    335347 
    336348 
     
    448460} 
    449461 
    450 void mgqueryfilterclass::mg_parse_query_params (const FilterRequest_t &/*request*/, 
     462void mgqueryfilterclass::parse_query_params (const FilterRequest_t &request, 
    451463                        vector<queryparamclass> &query_params, 
    452                         int &/*startresults*/, int &/*endresults*/, 
    453                         text_t &/*phrasematch*/, ostream &/*logout*/) { 
    454  
    455   //  outconvertclass text_t2ascii; 
     464                        int &startresults, int &endresults, 
     465                        text_t &phrasematch, ostream &logout) { 
     466 
     467  queryfilterclass::parse_query_params (request, query_params,  
     468                    startresults, endresults, logout); 
     469 
     470  phrasematch = filterOptions["PhraseMatch"].defaultValue; 
     471 
     472  // is there a better way to do this than iterate through all the options again?? 
     473  OptionValue_tarray::const_iterator options_here = request.filterOptions.begin(); 
     474  OptionValue_tarray::const_iterator options_end = request.filterOptions.end(); 
     475  while (options_here != options_end) { 
     476    if ((*options_here).name == "PhraseMatch") { 
     477      phrasematch = (*options_here).value; 
     478      break; 
     479    } 
     480    ++options_here; 
     481  } 
    456482   
    457483  vector<queryparamclass>::iterator query_here = query_params.begin(); 
  • main/trunk/greenstone2/runtime-src/src/colservr/mgqueryfilter.h

    r16445 r27064  
    6969                 docresultsclass &docs); 
    7070 
    71   virtual void mg_parse_query_params (const FilterRequest_t &request, 
    72                       vector<queryparamclass> &query_params, 
    73                       int &startresults, int &endresults, 
    74                       text_t &phrasematch, ostream &logout); 
     71  void parse_query_params (const FilterRequest_t &request, 
     72               vector<queryparamclass> &query_params, 
     73               int &startresults, int &endresults, 
     74               text_t &phrasematch, ostream &logout); 
    7575 
    7676   
  • main/trunk/greenstone2/runtime-src/src/colservr/queryfilter.cpp

    r16445 r27064  
    2828 
    2929 
    30 // translate will return true if successful 
    31 bool queryfilterclass::translate (dbclass *db_ptr, text_t& docnum, text_t &trans_OID) { 
    32   infodbclass info; 
    33  
    34   trans_OID.clear(); 
    35  
    36   // get the info 
    37   if (db_ptr == NULL) return false; 
    38   if (!db_ptr->getinfo(docnum, info)) return false; 
    39  
    40   // translate 
    41   if (info["section"].empty()) return false; 
    42  
    43   trans_OID = info["section"]; 
    44   return true; 
    45 } 
    46  
    47  
    48 // whether document results are needed 
    49 bool queryfilterclass::need_matching_docs (int filterResultOptions) { 
    50   return ((filterResultOptions & FROID) || (filterResultOptions & FRranking) || 
    51       (filterResultOptions & FRmetadata)); 
    52 } 
    53  
    54 // whether term information is needed 
    55 bool queryfilterclass::need_term_info (int filterResultOptions) { 
    56   return ((filterResultOptions & FRtermFreq) || (filterResultOptions & FRmatchTerms)); 
    57 } 
    5830 
    5931///////////////////////////////// 
     
    6133///////////////////////////////// 
    6234 
    63 // get the query parameters 
    64 void queryfilterclass::parse_query_params (const FilterRequest_t &request, 
    65                        vector<queryparamclass> &query_params, 
    66                        int &startresults, int &endresults, 
    67                        text_t &phrasematch, ostream &logout) { 
     35 
     36queryfilterclass::queryfilterclass () { 
     37  db_ptr = NULL; 
     38  textsearchptr = NULL; 
     39  maxnumeric = 4; 
     40 
     41  FilterOption_t filtopt; 
     42  filtopt.name = "CombineQuery"; 
     43  filtopt.type = FilterOption_t::enumeratedt; 
     44  filtopt.repeatable = FilterOption_t::onePerQuery; 
     45  filtopt.defaultValue = "and"; 
     46  filtopt.validValues.push_back("and"); 
     47  filtopt.validValues.push_back("or"); 
     48  filtopt.validValues.push_back("not"); 
     49  filterOptions["CombineQuery"] = filtopt; 
     50 
     51  // -- onePerQuery StartResults   integer 
     52  filtopt.clear(); 
     53  filtopt.name = "StartResults"; 
     54  filtopt.type = FilterOption_t::integert; 
     55  filtopt.repeatable = FilterOption_t::onePerQuery; 
     56  filtopt.defaultValue = "1"; 
     57  filtopt.validValues.push_back("1"); 
     58  filtopt.validValues.push_back("1000"); 
     59  filterOptions["StartResults"] = filtopt; 
     60 
     61  // -- onePerQuery EndResults     integer 
     62  filtopt.clear(); 
     63  filtopt.name = "EndResults"; 
     64  filtopt.type = FilterOption_t::integert; 
     65  filtopt.repeatable = FilterOption_t::onePerQuery; 
     66  filtopt.defaultValue = "10"; 
     67  filtopt.validValues.push_back("-1"); 
     68  filtopt.validValues.push_back("1000"); 
     69  filterOptions["EndResults"] = filtopt; 
     70 
     71  // -- onePerQuery QueryType      enumerated (boolean, ranked) 
     72  filtopt.clear(); 
     73  filtopt.name = "QueryType"; 
     74  filtopt.type = FilterOption_t::enumeratedt; 
     75  filtopt.repeatable = FilterOption_t::onePerQuery; 
     76  filtopt.defaultValue = "ranked"; 
     77  filtopt.validValues.push_back("boolean"); 
     78  filtopt.validValues.push_back("ranked"); 
     79  filterOptions["QueryType"] = filtopt; 
     80 
     81  // -- onePerQuery MatchMode      enumerated (some, all) 
     82  filtopt.clear(); 
     83  filtopt.name = "MatchMode"; 
     84  filtopt.type = FilterOption_t::enumeratedt; 
     85  filtopt.repeatable = FilterOption_t::onePerQuery; 
     86  filtopt.defaultValue = "some"; 
     87  filtopt.validValues.push_back("some"); 
     88  filtopt.validValues.push_back("all"); 
     89  filterOptions["MatchMode"] = filtopt; 
     90 
     91  // -- onePerTerm  Term           string ??? 
     92  filtopt.clear(); 
     93  filtopt.name = "Term"; 
     94  filtopt.type = FilterOption_t::stringt; 
     95  filtopt.repeatable = FilterOption_t::onePerTerm; 
     96  filtopt.defaultValue = ""; 
     97  filterOptions["Term"] = filtopt; 
     98 
     99  // -- onePerTerm  Casefold       boolean 
     100  filtopt.clear(); 
     101  filtopt.name = "Casefold"; 
     102  filtopt.type = FilterOption_t::booleant; 
     103  filtopt.repeatable = FilterOption_t::onePerTerm; 
     104  filtopt.defaultValue = "true"; 
     105  filtopt.validValues.push_back("false"); 
     106  filtopt.validValues.push_back("true"); 
     107  filterOptions["Casefold"] = filtopt; 
     108 
     109  // -- onePerTerm  Stem           boolean 
     110  filtopt.clear(); 
     111  filtopt.name = "Stem"; 
     112  filtopt.type = FilterOption_t::booleant; 
     113  filtopt.repeatable = FilterOption_t::onePerTerm; 
     114  filtopt.defaultValue = "false"; 
     115  filtopt.validValues.push_back("false"); 
     116  filtopt.validValues.push_back("true"); 
     117  filterOptions["Stem"] = filtopt; 
     118 
     119  // -- onePerTerm  AccentFold           boolean 
     120  filtopt.clear(); 
     121  filtopt.name = "AccentFold"; 
     122  filtopt.type = FilterOption_t::booleant; 
     123  filtopt.repeatable = FilterOption_t::onePerTerm; 
     124  filtopt.defaultValue = "false"; 
     125  filtopt.validValues.push_back("false"); 
     126  filtopt.validValues.push_back("true"); 
     127  filterOptions["AccentFold"] = filtopt; 
     128   
     129  // -- onePerTerm  Index          enumerated 
     130  filtopt.clear(); 
     131  filtopt.name = "Index"; 
     132  filtopt.type = FilterOption_t::enumeratedt; 
     133  filtopt.repeatable = FilterOption_t::onePerTerm; 
     134  filtopt.defaultValue = ""; 
     135  filterOptions["Index"] = filtopt; 
     136 
     137  // -- onePerTerm  Subcollection  enumerated 
     138  filtopt.clear(); 
     139  filtopt.name = "Subcollection"; 
     140  filtopt.type = FilterOption_t::enumeratedt; 
     141  filtopt.repeatable = FilterOption_t::onePerTerm; 
     142  filtopt.defaultValue = ""; 
     143  filterOptions["Subcollection"] = filtopt; 
     144 
     145  // -- onePerTerm  Language  enumerated 
     146  filtopt.clear(); 
     147  filtopt.name = "Language"; 
     148  filtopt.type = FilterOption_t::enumeratedt; 
     149  filtopt.repeatable = FilterOption_t::onePerTerm; 
     150  filtopt.defaultValue = ""; 
     151  filterOptions["Language"] = filtopt; 
     152 
     153  // -- onePerQuery  Maxdocs  integer 
     154  filtopt.clear(); 
     155  filtopt.name = "Maxdocs"; 
     156  filtopt.type = FilterOption_t::integert; 
     157  filtopt.repeatable = FilterOption_t::onePerQuery; 
     158  filtopt.defaultValue = "200"; 
     159  filtopt.validValues.push_back("-1"); 
     160  filtopt.validValues.push_back("1000"); 
     161  filterOptions["Maxdocs"] = filtopt; 
     162 
     163} 
     164 
     165queryfilterclass::~queryfilterclass () { 
     166  // don't delete db_ptr or textsearchptr here, they'll be cleaned up by the source 
     167} 
     168 
     169void queryfilterclass::configure (const text_t &key, const text_tarray &cfgline) { 
     170  filterclass::configure (key, cfgline); 
     171 
     172  if (key == "indexmap") { 
     173    indexmap.importmap (cfgline); 
     174     
     175    // update the list of indexes in the filter information 
     176    text_tarray options; 
     177    indexmap.gettoarray (options); 
     178    filterOptions["Index"].validValues = options; 
     179 
     180  } else if (key == "defaultindex") { 
     181    indexmap.from2to (cfgline[0], filterOptions["Index"].defaultValue); 
     182 
     183  } else if (key == "subcollectionmap") { 
     184    subcollectionmap.importmap (cfgline); 
     185 
     186    // update the list of subcollections in the filter information 
     187    text_tarray options; 
     188    subcollectionmap.gettoarray (options); 
     189    filterOptions["Subcollection"].validValues = options; 
     190 
     191  } else if (key == "defaultsubcollection") { 
     192    subcollectionmap.from2to (cfgline[0], filterOptions["Subcollection"].defaultValue); 
     193 
     194  } else if (key == "languagemap") { 
     195    languagemap.importmap (cfgline); 
     196 
     197    // update the list of languages in the filter information 
     198    text_tarray options; 
     199    languagemap.gettoarray (options); 
     200    filterOptions["Language"].validValues = options; 
     201 
     202  } else if (key == "defaultlanguage") { 
     203    languagemap.from2to (cfgline[0], filterOptions["Language"].defaultValue); 
     204  } else if (key == "indexstem") { 
     205    indexstem = cfgline[0]; 
     206  } else if (key == "maxnumeric") { 
     207    maxnumeric = cfgline[0].getint(); 
     208  } 
     209   
     210} 
     211 
     212bool queryfilterclass::init (ostream &logout) { 
    68213  outconvertclass text_t2ascii; 
    69214 
    70   // set defaults for the return parameters 
    71   query_params.erase(query_params.begin(), query_params.end()); 
    72   startresults = filterOptions["StartResults"].defaultValue.getint(); 
    73   endresults = filterOptions["EndResults"].defaultValue.getint(); 
    74   phrasematch = filterOptions["PhraseMatch"].defaultValue; 
    75  
    76   // set defaults for query parameters 
    77   queryparamclass query; 
    78   query.combinequery = "or"; // first one must be "or" 
     215  if (!filterclass::init(logout)) return false; 
     216 
     217  if (filterOptions["Index"].defaultValue.empty()) { 
     218    // use first index in map as default if no default is set explicitly 
     219    text_tarray fromarray; 
     220    indexmap.getfromarray(fromarray); 
     221    if (fromarray.size()) { 
     222      filterOptions["Index"].defaultValue = fromarray[0]; 
     223    } 
     224  } 
     225 
     226  if (filterOptions["Subcollection"].defaultValue.empty()) { 
     227    // use first subcollection in map as default if no default is set explicitly 
     228    text_tarray fromarray; 
     229    subcollectionmap.getfromarray(fromarray); 
     230    if (fromarray.size()) { 
     231      filterOptions["Subcollection"].defaultValue = fromarray[0]; 
     232    } 
     233  } 
     234 
     235  if (filterOptions["Language"].defaultValue.empty()) { 
     236    // use first language in map as default if no default is set explicitly 
     237    text_tarray fromarray; 
     238    languagemap.getfromarray(fromarray); 
     239    if (fromarray.size()) { 
     240      filterOptions["Language"].defaultValue = fromarray[0]; 
     241    } 
     242  } 
     243 
     244  if (db_ptr == NULL) { 
     245    // most likely a configuration problem 
     246    logout << text_t2ascii  
     247       << "configuration error: queryfilter contains a null dbclass\n\n"; 
     248    return false; 
     249  } 
     250 
     251  // get the filename for the database and make sure it exists 
     252  if (indexstem.empty()) { 
     253    indexstem = collection; 
     254  } 
     255  db_filename = resolve_db_filename(indexstem,db_ptr->getfileextension()); 
     256  if (!file_exists(db_filename)) { 
     257    logout << text_t2ascii 
     258       << "warning: database \"" << db_filename << "\" does not exist\n\n"; 
     259    //return false; 
     260  } 
     261 
     262  return true; 
     263} 
     264 
     265void queryfilterclass::set_queryparam_defaults(queryparamclass &query ) { 
     266   
    79267  query.collection = collection; 
    80268  query.index = filterOptions["Index"].defaultValue; 
     
    89277  query.maxdocs = filterOptions["Maxdocs"].defaultValue.getint(); 
    90278  query.level = filterOptions["Level"].defaultValue; 
    91   query.filterstring = filterOptions["FilterString"].defaultValue;  // Lucene specific 
    92   query.sortfield = filterOptions["SortField"].defaultValue;  // Lucene specific 
    93   query.fuzziness = filterOptions["Fuzziness"].defaultValue;  // Lucene specific 
    94279  query.maxnumeric = maxnumeric; 
     280 
     281} 
     282 
     283bool queryfilterclass::set_queryparam_field(OptionValue_t option, queryparamclass &query) { 
     284 
     285if (option.name == "QueryType") { 
     286      query.search_type = (option.value == "ranked"); 
     287    } else if (option.name == "MatchMode") { 
     288      query.match_mode = (option.value == "all"); 
     289      if (query.match_mode == 1) query.maxdocs = -1; 
     290    } else if (option.name == "Term") { 
     291      query.querystring = option.value; 
     292    } else if (option.name == "Casefold") { 
     293      query.casefolding = (option.value == "true"); 
     294    } else if (option.name == "Stem") { 
     295      query.stemming = (option.value == "true"); 
     296    } else if (option.name == "AccentFold") { 
     297      query.accentfolding = (option.value == "true"); 
     298    } else if (option.name == "Index"&& option.value !="") { 
     299      query.index = option.value; 
     300    } else if (option.name == "Subcollection") { 
     301      query.subcollection = option.value; 
     302    } else if (option.name == "Language") { 
     303      query.language = option.value; 
     304    } else if (option.name == "Maxdocs") { 
     305      query.maxdocs = option.value.getint(); 
     306    // } else if (option.name == "PhraseMatch") { 
     307    //   phrasematch = option.value; 
     308    } else if (option.name == "Level") { 
     309      query.level = option.value; 
     310    } else if (option.name == "FilterString") { 
     311      query.filterstring = option.value; 
     312    } else if (option.name == "SortField") { 
     313      query.sortfield = option.value; 
     314    } else if (option.name == "SortOrder") { 
     315      query.sortorder = (option.value == "descending"); 
     316    } else if (option.name == "Fuzziness") { 
     317      query.fuzziness = option.value; 
     318 }  
     319} 
     320// get the query parameters 
     321void queryfilterclass::parse_query_params (const FilterRequest_t &request, 
     322                       vector<queryparamclass> &query_params, 
     323                       int &startresults, int &endresults, 
     324                       ostream &logout) { 
     325  outconvertclass text_t2ascii; 
     326 
     327  // set defaults for the return parameters 
     328  query_params.erase(query_params.begin(), query_params.end()); 
     329  startresults = filterOptions["StartResults"].defaultValue.getint(); 
     330  endresults = filterOptions["EndResults"].defaultValue.getint(); 
     331 
     332  // set defaults for query parameters 
     333  queryparamclass query; 
     334  query.combinequery = "or"; // first one must be "or" 
     335  set_queryparam_defaults(query); 
    95336  OptionValue_tarray::const_iterator options_here = request.filterOptions.begin(); 
    96337  OptionValue_tarray::const_iterator options_end = request.filterOptions.end(); 
     
    108349 
    109350      // set defaults for query parameters 
    110       query.collection = collection; 
    111       query.index = filterOptions["Index"].defaultValue; 
    112       query.subcollection = filterOptions["Subcollection"].defaultValue; 
    113       query.language = filterOptions["Language"].defaultValue; 
    114       query.querystring.clear(); 
    115       query.search_type = (filterOptions["QueryType"].defaultValue == "ranked"); 
    116       query.match_mode = (filterOptions["MatchMode"].defaultValue == "all"); 
    117       query.casefolding = (filterOptions["Casefold"].defaultValue == "true"); 
    118       query.stemming = (filterOptions["Stem"].defaultValue == "true"); 
    119       query.accentfolding = (filterOptions["AccentFold"].defaultValue == "true"); 
    120       query.level = filterOptions["Level"].defaultValue; 
    121       query.filterstring = filterOptions["FilterString"].defaultValue;  // Lucene specific 
    122       query.sortfield = filterOptions["SortField"].defaultValue;  // Lucene specific 
    123       query.fuzziness = filterOptions["Fuzziness"].defaultValue;  // Lucene specific 
    124       query.maxnumeric = maxnumeric; 
     351      set_queryparam_defaults(query); 
     352 
    125353      // "all", needed when combining queries where the document results are needed 
    126354      if (need_matching_docs (request.filterResultOptions)) query.maxdocs = -1;  
    127       else query.maxdocs = filterOptions["Maxdocs"].defaultValue.getint(); 
    128355       
    129356    } else if ((*options_here).name == "StartResults") { 
     
    131358    } else if ((*options_here).name == "EndResults") { 
    132359      endresults = (*options_here).value.getint(); 
    133     } else if ((*options_here).name == "QueryType") { 
    134       query.search_type = ((*options_here).value == "ranked"); 
    135     } else if ((*options_here).name == "MatchMode") { 
    136       query.match_mode = ((*options_here).value == "all"); 
    137       if (query.match_mode == 1) query.maxdocs = -1; 
    138     } else if ((*options_here).name == "Term") { 
    139       query.querystring = (*options_here).value; 
    140     } else if ((*options_here).name == "Casefold") { 
    141       query.casefolding = ((*options_here).value == "true"); 
    142     } else if ((*options_here).name == "Stem") { 
    143       query.stemming = ((*options_here).value == "true"); 
    144     } else if ((*options_here).name == "AccentFold") { 
    145       query.accentfolding = ((*options_here).value == "true"); 
    146     } else if ((*options_here).name == "Index"&& (*options_here).value !="") { 
    147       query.index = (*options_here).value; 
    148     } else if ((*options_here).name == "Subcollection") { 
    149       query.subcollection = (*options_here).value; 
    150     } else if ((*options_here).name == "Language") { 
    151       query.language = (*options_here).value; 
    152     } else if ((*options_here).name == "Maxdocs") { 
    153       query.maxdocs = (*options_here).value.getint(); 
    154     } else if ((*options_here).name == "PhraseMatch") { 
    155       phrasematch = (*options_here).value; 
    156     } else if ((*options_here).name == "Level") { 
    157       query.level = (*options_here).value; 
    158     } else if ((*options_here).name == "FilterString") { 
    159       query.filterstring = (*options_here).value; 
    160     } else if ((*options_here).name == "SortField") { 
    161       query.sortfield = (*options_here).value; 
    162     } else if ((*options_here).name == "Fuzziness") { 
    163       query.fuzziness = (*options_here).value; 
    164     } else { 
     360    } else if (!set_queryparam_field(*options_here, query)) { 
    165361      logout << text_t2ascii 
    166362         << "warning: unknown queryfilter option \"" 
     
    183379 
    184380 
    185  
    186 queryfilterclass::queryfilterclass () { 
    187   db_ptr = NULL; 
    188   textsearchptr = NULL; 
    189   maxnumeric = 4; 
    190  
    191   FilterOption_t filtopt; 
    192   filtopt.name = "CombineQuery"; 
    193   filtopt.type = FilterOption_t::enumeratedt; 
    194   filtopt.repeatable = FilterOption_t::onePerQuery; 
    195   filtopt.defaultValue = "and"; 
    196   filtopt.validValues.push_back("and"); 
    197   filtopt.validValues.push_back("or"); 
    198   filtopt.validValues.push_back("not"); 
    199   filterOptions["CombineQuery"] = filtopt; 
    200  
    201   // -- onePerQuery StartResults   integer 
    202   filtopt.clear(); 
    203   filtopt.name = "StartResults"; 
    204   filtopt.type = FilterOption_t::integert; 
    205   filtopt.repeatable = FilterOption_t::onePerQuery; 
    206   filtopt.defaultValue = "1"; 
    207   filtopt.validValues.push_back("1"); 
    208   filtopt.validValues.push_back("1000"); 
    209   filterOptions["StartResults"] = filtopt; 
    210  
    211   // -- onePerQuery EndResults     integer 
    212   filtopt.clear(); 
    213   filtopt.name = "EndResults"; 
    214   filtopt.type = FilterOption_t::integert; 
    215   filtopt.repeatable = FilterOption_t::onePerQuery; 
    216   filtopt.defaultValue = "10"; 
    217   filtopt.validValues.push_back("-1"); 
    218   filtopt.validValues.push_back("1000"); 
    219   filterOptions["EndResults"] = filtopt; 
    220  
    221   // -- onePerQuery QueryType      enumerated (boolean, ranked) 
    222   filtopt.clear(); 
    223   filtopt.name = "QueryType"; 
    224   filtopt.type = FilterOption_t::enumeratedt; 
    225   filtopt.repeatable = FilterOption_t::onePerQuery; 
    226   filtopt.defaultValue = "ranked"; 
    227   filtopt.validValues.push_back("boolean"); 
    228   filtopt.validValues.push_back("ranked"); 
    229   filterOptions["QueryType"] = filtopt; 
    230  
    231   // -- onePerQuery MatchMode      enumerated (some, all) 
    232   filtopt.clear(); 
    233   filtopt.name = "MatchMode"; 
    234   filtopt.type = FilterOption_t::enumeratedt; 
    235   filtopt.repeatable = FilterOption_t::onePerQuery; 
    236   filtopt.defaultValue = "some"; 
    237   filtopt.validValues.push_back("some"); 
    238   filtopt.validValues.push_back("all"); 
    239   filterOptions["MatchMode"] = filtopt; 
    240  
    241   // -- onePerTerm  Term           string ??? 
    242   filtopt.clear(); 
    243   filtopt.name = "Term"; 
    244   filtopt.type = FilterOption_t::stringt; 
    245   filtopt.repeatable = FilterOption_t::onePerTerm; 
    246   filtopt.defaultValue = ""; 
    247   filterOptions["Term"] = filtopt; 
    248  
    249   // -- onePerTerm  Casefold       boolean 
    250   filtopt.clear(); 
    251   filtopt.name = "Casefold"; 
    252   filtopt.type = FilterOption_t::booleant; 
    253   filtopt.repeatable = FilterOption_t::onePerTerm; 
    254   filtopt.defaultValue = "true"; 
    255   filtopt.validValues.push_back("false"); 
    256   filtopt.validValues.push_back("true"); 
    257   filterOptions["Casefold"] = filtopt; 
    258  
    259   // -- onePerTerm  Stem           boolean 
    260   filtopt.clear(); 
    261   filtopt.name = "Stem"; 
    262   filtopt.type = FilterOption_t::booleant; 
    263   filtopt.repeatable = FilterOption_t::onePerTerm; 
    264   filtopt.defaultValue = "false"; 
    265   filtopt.validValues.push_back("false"); 
    266   filtopt.validValues.push_back("true"); 
    267   filterOptions["Stem"] = filtopt; 
    268  
    269   // -- onePerTerm  AccentFold           boolean 
    270   filtopt.clear(); 
    271   filtopt.name = "AccentFold"; 
    272   filtopt.type = FilterOption_t::booleant; 
    273   filtopt.repeatable = FilterOption_t::onePerTerm; 
    274   filtopt.defaultValue = "false"; 
    275   filtopt.validValues.push_back("false"); 
    276   filtopt.validValues.push_back("true"); 
    277   filterOptions["AccentFold"] = filtopt; 
    278    
    279   // -- onePerTerm  Index          enumerated 
    280   filtopt.clear(); 
    281   filtopt.name = "Index"; 
    282   filtopt.type = FilterOption_t::enumeratedt; 
    283   filtopt.repeatable = FilterOption_t::onePerTerm; 
    284   filtopt.defaultValue = ""; 
    285   filterOptions["Index"] = filtopt; 
    286  
    287   // -- onePerTerm  Subcollection  enumerated 
    288   filtopt.clear(); 
    289   filtopt.name = "Subcollection"; 
    290   filtopt.type = FilterOption_t::enumeratedt; 
    291   filtopt.repeatable = FilterOption_t::onePerTerm; 
    292   filtopt.defaultValue = ""; 
    293   filterOptions["Subcollection"] = filtopt; 
    294  
    295   // -- onePerTerm  Language  enumerated 
    296   filtopt.clear(); 
    297   filtopt.name = "Language"; 
    298   filtopt.type = FilterOption_t::enumeratedt; 
    299   filtopt.repeatable = FilterOption_t::onePerTerm; 
    300   filtopt.defaultValue = ""; 
    301   filterOptions["Language"] = filtopt; 
    302  
    303   // -- onePerQuery  Maxdocs  integer 
    304   filtopt.clear(); 
    305   filtopt.name = "Maxdocs"; 
    306   filtopt.type = FilterOption_t::integert; 
    307   filtopt.repeatable = FilterOption_t::onePerQuery; 
    308   filtopt.defaultValue = "200"; 
    309   filtopt.validValues.push_back("-1"); 
    310   filtopt.validValues.push_back("1000"); 
    311   filterOptions["Maxdocs"] = filtopt; 
    312  
    313   // -- onePerQuery  PhraseMatch  enumerated 
    314   filtopt.clear(); 
    315   filtopt.name = "PhraseMatch"; 
    316   filtopt.type = FilterOption_t::enumeratedt; 
    317   filtopt.repeatable = FilterOption_t::onePerQuery; 
    318   filtopt.defaultValue = "some_phrases"; 
    319   filtopt.validValues.push_back ("all_phrases"); 
    320   filtopt.validValues.push_back ("some_phrases"); 
    321   filtopt.validValues.push_back ("all_docs"); 
    322   filterOptions["PhraseMatch"] = filtopt; 
    323 } 
    324  
    325 queryfilterclass::~queryfilterclass () { 
    326   // don't delete db_ptr or textsearchptr here, they'll be cleaned up by the source 
    327 } 
    328  
    329 void queryfilterclass::configure (const text_t &key, const text_tarray &cfgline) { 
    330   filterclass::configure (key, cfgline); 
    331  
    332   if (key == "indexmap") { 
    333     indexmap.importmap (cfgline); 
    334      
    335     // update the list of indexes in the filter information 
    336     text_tarray options; 
    337     indexmap.gettoarray (options); 
    338     filterOptions["Index"].validValues = options; 
    339  
    340   } else if (key == "defaultindex") { 
    341     indexmap.from2to (cfgline[0], filterOptions["Index"].defaultValue); 
    342  
    343   } else if (key == "subcollectionmap") { 
    344     subcollectionmap.importmap (cfgline); 
    345  
    346     // update the list of subcollections in the filter information 
    347     text_tarray options; 
    348     subcollectionmap.gettoarray (options); 
    349     filterOptions["Subcollection"].validValues = options; 
    350  
    351   } else if (key == "defaultsubcollection") { 
    352     subcollectionmap.from2to (cfgline[0], filterOptions["Subcollection"].defaultValue); 
    353  
    354   } else if (key == "languagemap") { 
    355     languagemap.importmap (cfgline); 
    356  
    357     // update the list of languages in the filter information 
    358     text_tarray options; 
    359     languagemap.gettoarray (options); 
    360     filterOptions["Language"].validValues = options; 
    361  
    362   } else if (key == "defaultlanguage") { 
    363     languagemap.from2to (cfgline[0], filterOptions["Language"].defaultValue); 
    364   } else if (key == "indexstem") { 
    365     indexstem = cfgline[0]; 
    366   } else if (key == "maxnumeric") { 
    367     maxnumeric = cfgline[0].getint(); 
    368   } 
    369    
    370 } 
    371  
    372 bool queryfilterclass::init (ostream &logout) { 
    373   outconvertclass text_t2ascii; 
    374  
    375   if (!filterclass::init(logout)) return false; 
    376  
    377   if (filterOptions["Index"].defaultValue.empty()) { 
    378     // use first index in map as default if no default is set explicitly 
    379     text_tarray fromarray; 
    380     indexmap.getfromarray(fromarray); 
    381     if (fromarray.size()) { 
    382       filterOptions["Index"].defaultValue = fromarray[0]; 
    383     } 
    384   } 
    385  
    386   if (filterOptions["Subcollection"].defaultValue.empty()) { 
    387     // use first subcollection in map as default if no default is set explicitly 
    388     text_tarray fromarray; 
    389     subcollectionmap.getfromarray(fromarray); 
    390     if (fromarray.size()) { 
    391       filterOptions["Subcollection"].defaultValue = fromarray[0]; 
    392     } 
    393   } 
    394  
    395   if (filterOptions["Language"].defaultValue.empty()) { 
    396     // use first language in map as default if no default is set explicitly 
    397     text_tarray fromarray; 
    398     languagemap.getfromarray(fromarray); 
    399     if (fromarray.size()) { 
    400       filterOptions["Language"].defaultValue = fromarray[0]; 
    401     } 
    402   } 
    403  
    404   if (db_ptr == NULL) { 
    405     // most likely a configuration problem 
    406     logout << text_t2ascii  
    407        << "configuration error: queryfilter contains a null dbclass\n\n"; 
    408     return false; 
    409   } 
    410  
    411   // get the filename for the database and make sure it exists 
    412   if (indexstem.empty()) { 
    413     indexstem = collection; 
    414   } 
    415   db_filename = resolve_db_filename(indexstem,db_ptr->getfileextension()); 
    416   if (!file_exists(db_filename)) { 
    417     logout << text_t2ascii 
    418        << "warning: database \"" << db_filename << "\" does not exist\n\n"; 
    419     //return false; 
    420   } 
    421  
     381// translate will return true if successful 
     382bool queryfilterclass::translate (dbclass *db_ptr, text_t& docnum, text_t &trans_OID) { 
     383  infodbclass info; 
     384 
     385  trans_OID.clear(); 
     386 
     387  // get the info 
     388  if (db_ptr == NULL) return false; 
     389  if (!db_ptr->getinfo(docnum, info)) return false; 
     390 
     391  // translate 
     392  if (info["section"].empty()) return false; 
     393 
     394  trans_OID = info["section"]; 
    422395  return true; 
    423396} 
    424397 
     398 
     399// whether document results are needed 
     400bool queryfilterclass::need_matching_docs (int filterResultOptions) { 
     401  return ((filterResultOptions & FROID) || (filterResultOptions & FRranking) || 
     402      (filterResultOptions & FRmetadata)); 
     403} 
     404 
     405// whether term information is needed 
     406bool queryfilterclass::need_term_info (int filterResultOptions) { 
     407  return ((filterResultOptions & FRtermFreq) || (filterResultOptions & FRmatchTerms)); 
     408} 
  • main/trunk/greenstone2/runtime-src/src/colservr/queryfilter.h

    r16445 r27064  
    5656  int maxnumeric; 
    5757 
    58    // get the query parameters 
     58  void set_queryparam_defaults(queryparamclass &query ); 
     59  bool set_queryparam_field(OptionValue_t option, queryparamclass &query); 
    5960  void parse_query_params (const FilterRequest_t &request, 
    6061               vector<queryparamclass> &query_params, 
    6162               int &startresults, int &endresults, 
    62                text_t &phrasematch, ostream &logout); 
     63               ostream &logout); 
    6364 
    6465  // do query that might involve multiple sub queries