Ignore:
Timestamp:
2013-03-12T14:37:44+13:00 (11 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 edited

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
Note: See TracChangeset for help on using the changeset viewer.