11#include <boost/filesystem.hpp>
12#include <boost/regex.hpp>
55 lQueryStringWordList);
56 if (lQueryStringWordList.size() == 1) {
62 WordSet_T::const_iterator itWord = ioWordSet.find (iQueryString);
63 if (shouldBeKept ==
true && itWord == ioWordSet.end()) {
64 ioWordSet.insert (iQueryString);
65 ioWordList.push_back (iQueryString);
80 for (ResultList_T::const_iterator itResult = lResultList.begin();
81 itResult != lResultList.end(); ++itResult) {
83 const Result* lResult_ptr = *itResult;
84 assert (lResult_ptr != NULL);
91 if (hasFullTextMatched ==
false) {
94 assert (hasFullTextMatched ==
true);
132 const Xapian::Database& iDatabase,
135 const std::string& iNegativeQuery =
"") {
144 for (StringPartition::StringPartition_T::const_iterator itSet =
146 itSet != iStringPartition.
_partition.end(); ++itSet) {
162 for (StringSet::StringSet_T::const_iterator itString =
163 lStringSet.
_set.begin();
164 itString != lStringSet.
_set.end(); ++itString) {
166 const std::string lQueryString (*itString);
181 const std::string& lMatchedString =
182 lResult.
fullTextMatch (iDatabase, lQueryString, iNegativeQuery);
186 if (lMatchedString.empty() ==
true) {
193 <<
"========================================="
194 << std::endl <<
"Result holder: "
195 << lResultHolder.
toString() << std::endl
196 <<
"========================================="
197 << std::endl << std::endl);
203 }
catch (
const Xapian::Error& error) {
230 const bool doesBestMatchingResultHolderExist =
233 if (doesBestMatchingResultHolderExist ==
true) {
243 <<
", and has got a weight of "
245 <<
"%. The corrected string set is: "
246 << lCorrectedStringSet);
256 bool RequestInterpreter::areAllCodeOrGeoID (
const TravelQuery_T& iQueryString,
258 bool areAllWordsCodes =
true;
262 for (WordList_T::const_iterator itWord = ioWordList.begin();
263 itWord != ioWordList.end(); ++itWord) {
264 const std::string& lWord = *itWord;
267 const boost::regex lIATACodeExp (
"^[[:alpha:]]{3}$");
268 const bool lMatchesWithIATACode = regex_match (lWord, lIATACodeExp);
271 const boost::regex lICAOCodeExp (
"^([[:alpha:]]|[[:digit:]]){4}$");
272 const bool lMatchesWithICAOCode = regex_match (lWord, lICAOCodeExp);
276 lUNLOCodeExp (
"^[[:alpha:]]{2}([[:alpha:]]|[[:digit:]]){3}$");
277 const bool lMatchesWithUNLOCode = regex_match (lWord, lUNLOCodeExp);
280 const boost::regex lGeoIDCodeExp (
"^[[:digit:]]{1,12}$");
281 const bool lMatchesWithGeoID = regex_match (lWord, lGeoIDCodeExp);
287 if (lMatchesWithIATACode ==
false && lMatchesWithICAOCode ==
false
288 && lMatchesWithUNLOCode ==
false && lMatchesWithGeoID ==
false) {
289 areAllWordsCodes =
false;
294 return areAllWordsCodes;
308 for (LocationList_T::const_iterator itLocation = iLocationList.begin();
309 itLocation != iLocationList.end(); ++itLocation) {
310 const Location& lLocation = *itLocation;
314 if (lPageRank > lMaxPageRank) {
315 lMaxPageRank = lPageRank;
316 oLocation = lLocation;
345 soci::session* lSociSession_ptr =
347 if (lSociSession_ptr == NULL) {
348 std::ostringstream oStr;
349 oStr <<
"The " << iSQLDBType.
describe()
350 <<
" database is not accessible. Connection string: "
351 << iSQLDBConnStr << std::endl
352 <<
"Hint: launch the 'opentrep-dbmgr' program and "
353 <<
"see the 'tutorial' command.";
357 assert (lSociSession_ptr != NULL);
360 for (WordList_T::const_iterator itWord = iCodeList.begin();
361 itWord != iCodeList.end(); ++itWord) {
362 const std::string& lWord = *itWord;
365 const boost::regex lIATACodeExp (
"^[[:alpha:]]{3}$");
366 const bool lMatchesWithIATACode = regex_match (lWord, lIATACodeExp);
367 if (lMatchesWithIATACode ==
true) {
370 const bool lUniqueEntry =
true;
373 ioLocationList, lUniqueEntry);
374 oNbOfMatches += lNbOfEntries;
379 const boost::regex lICAOCodeExp (
"^([[:alpha:]]|[[:digit:]]){4}$");
380 const bool lMatchesWithICAOCode = regex_match (lWord, lICAOCodeExp);
381 if (lMatchesWithICAOCode ==
true) {
387 oNbOfMatches += lNbOfEntries;
393 lUNLOCodeExp (
"^[[:alpha:]]{2}([[:alpha:]]|[[:digit:]]){3}$");
394 const bool lMatchesWithUNLOCode = regex_match (lWord, lUNLOCodeExp);
395 if (lMatchesWithUNLOCode ==
true) {
398 const bool lUniqueEntry =
true;
401 ioLocationList, lUniqueEntry);
402 oNbOfMatches += lNbOfEntries;
407 const boost::regex lGeoIDCodeExp (
"^[[:digit:]]{1,12}$");
408 const bool lMatchesWithGeoID = regex_match (lWord, lGeoIDCodeExp);
409 if (lMatchesWithGeoID ==
true) {
413 boost::lexical_cast<GeonamesID_T> (lWord);
419 oNbOfMatches += lNbOfEntries;
421 }
catch (boost::bad_lexical_cast& eCast) {
423 <<
"') cannot be understood.");
433 interpretTravelRequest (
const TravelDBFilePath_T& iTravelDBFilePath,
434 const DBType& iSQLDBType,
435 const SQLDBConnectionString_T& iSQLDBConnStr,
439 const OTransliterator& iTransliterator) {
443 assert (iTravelQuery.empty() ==
false);
447 boost::filesystem::path lTravelDBFilePath (iTravelDBFilePath.begin(),
448 iTravelDBFilePath.end());
449 if (!(boost::filesystem::exists (lTravelDBFilePath)
450 && boost::filesystem::is_directory (lTravelDBFilePath))) {
451 std::ostringstream oStr;
452 oStr <<
"The file-path to the Xapian database/index ('"
453 << iTravelDBFilePath <<
"') does not exist or is not a directory. ";
454 oStr <<
"That usually means that the OpenTREP indexer (opentrep-indexer) "
455 <<
"has not been launched yet, or that it has operated "
456 <<
"on a different Xapian database/index file-path.";
458 throw FileNotFoundException (oStr.str());
462 Xapian::Database lXapianDatabase (iTravelDBFilePath);
466 <<
"=========================================");
470 std::string lPositiveQuery, lNegativeQuery;
471 std::istringstream iss(iTravelQuery);
473 bool firstPos =
true, firstNeg =
true;
474 while (iss >> word) {
475 if (word.length() > 1 && word[0] ==
'-') {
476 if (!firstNeg) lNegativeQuery +=
" ";
477 lNegativeQuery += word;
480 if (!firstPos) lPositiveQuery +=
" ";
481 lPositiveQuery += word;
486 if (lPositiveQuery.empty()) {
487 lPositiveQuery = iTravelQuery;
488 lNegativeQuery.clear();
493 QuerySlices lQuerySlices (lXapianDatabase, lPositiveQuery, iTransliterator);
498 const TravelQuery_T& lNormalisedQueryString = lQuerySlices.getQueryString();
499 if (!(iTravelQuery == lNormalisedQueryString)) {
507 lQuerySlices.getStringPartitionList();
508 for (StringPartitionList_T::const_iterator itSlice =
509 lStringPartitionList.begin();
510 itSlice != lStringPartitionList.end(); ++itSlice) {
511 StringPartition lStringPartition = *itSlice;
512 const std::string& lTravelQuerySlice = lStringPartition.getInitialString();
519 ResultCombination& lResultCombination =
533 const bool areAllWordsCodes =
534 areAllCodeOrGeoID (lTravelQuerySlice, lCodeList);
537 if (areAllWordsCodes ==
true && !(iSQLDBType ==
DBType::NODB)) {
546 <<
") is made only of IATA/ICAO/UNLOCODE codes "
547 <<
"or Geonames ID. The " << iSQLDBType.describe()
548 <<
" SQL database (" << iSQLDBConnStr
549 <<
") will be used. "
550 <<
"The Xapian database/index will not be used");
553 ioLocationList, ioWordList);
556 if (lNbOfMatches == 0) {
570 <<
"The Xapian database will be used instead");
573 <<
") has got items/words, which are neither "
574 <<
"IATA/ICAO codes nor Geonames ID. "
575 <<
"The Xapian database/index will be used");
583 lResultCombination, ioWordList, lNegativeQuery);
588 lResultCombination.calculateAllWeights();
606 <<
"========================================="
607 << std::endl <<
"Summary:" << std::endl
608 << lPlaceHolder.toShortString() << std::endl
609 <<
"========================================="
616 lPlaceHolder.createLocations (ioLocationList);
620 oNbOfMatches = ioLocationList.size();
#define OPENTREP_LOG_ERROR(iToBeLogged)
#define OPENTREP_LOG_DEBUG(iToBeLogged)
static NbOfDBEntries_T getPORByICAOCode(soci::session &, const ICAOCode_T &, LocationList_T &)
static soci::session * initSQLDBSession(const DBType &, const SQLDBConnectionString_T &)
static NbOfDBEntries_T getPORByUNLOCode(soci::session &, const UNLOCode_T &, LocationList_T &, const bool iUniqueEntry)
static NbOfDBEntries_T getPORByGeonameID(soci::session &, const GeonamesID_T &, LocationList_T &)
static NbOfDBEntries_T getPORByIATACode(soci::session &, const IATACode_T &, LocationList_T &, const bool iUniqueEntry)
static FacPlaceHolder & instance()
static void initLinkWithPlace(PlaceHolder &, Place &)
static FacPlace & instance()
static void initLinkWithResultHolder(ResultCombination &, ResultHolder &)
static FacResultCombination & instance()
ResultCombination & create(const TravelQuery_T &iQueryString)
static void initLinkWithResult(ResultHolder &, Result &)
static FacResultHolder & instance()
ResultHolder & create(const TravelQuery_T &iQueryString, const Xapian::Database &iDatabase)
Result & create(const TravelQuery_T &, const Xapian::Database &)
static FacResult & instance()
Class modelling a place/POR (point of reference).
std::string toString() const
Class wrapping functions on a list of ResultHolder objects.
const ResultHolder & getBestMatchingResultHolder() const
bool chooseBestMatchingResultHolder()
StringSet getCorrectedStringSet() const
const Percentage_T & getBestMatchingWeight() const
std::string describeShortKey() const
Class wrapping functions on a list of Result objects.
std::string describeShortKey() const
const ResultList_T & getResultList() const
std::string toString() const
Class wrapping a set of Xapian documents having matched a given query string.
bool hasFullTextMatched() const
const RawDataString_T & getBestDocData() const
void fillPlace(Place &) const
static Location retrieveLocation(const Xapian::Document &)
std::string fullTextMatch(const Xapian::Database &, const TravelQuery_T &, const std::string &="")
static void tokeniseStringIntoWordList(const TravelQuery_T &, WordList_T &)
std::list< Word_T > WordList_T
void addUnmatchedWord(const TravelQuery_T &iQueryString, WordList_T &ioWordList, WordSet_T &ioWordSet)
void chooseBestMatchingResultHolder(ResultCombination &ioResultCombination)
unsigned int NbOfDBEntries_T
std::string TravelQuery_T
std::list< Location > LocationList_T
void createPlaces(const ResultCombination &iResultCombination, PlaceHolder &ioPlaceHolder)
NbOfMatches_T getLocationList(const DBType &iSQLDBType, const SQLDBConnectionString_T &iSQLDBConnStr, const WordList_T &iCodeList, LocationList_T &ioLocationList, WordList_T &ioWordList)
Location getBestMatchingLocation(const LocationList_T &iLocationList)
std::set< std::string > WordSet_T
unsigned short NbOfMatches_T
unsigned int GeonamesID_T
void searchString(const StringPartition &iStringPartition, const Xapian::Database &iDatabase, ResultCombination &ioResultCombination, WordList_T &ioWordList, const std::string &iNegativeQuery="")
std::list< Result * > ResultList_T
std::list< StringPartition > StringPartitionList_T
std::vector< std::string > WordList_T
Enumeration of database types.
const std::string describe() const
static bool shouldKeep(const std::string &iPhrase, const std::string &iWord)
Structure modelling a (geographical) location.
const PageRank_T & getPageRank() const
StringPartition_T _partition
Class holding a set of strings, e.g., {"rio", "de", "janeiro"}.
std::string describe() const