8 #include <Poco/AutoPtr.h>
28 client(nullptr), field_names(nullptr), field_weights(nullptr), fieldsCount(0), index_names(nullptr), index_weights(nullptr),
29 indexesCount(0), fObj(fObj_), message(fObj.getCustomMessage()),
31 _StopSearchd(stopSearchd_), _isConnected(false), _isStoppedSearchd(true), timeoutedRequests(0), defaultRequestTimeout(input_json_message_const::
defaultTimeoutValue),
32 allowedFields(), fullSchemaNames(),
requestInfo(), resultData(), resultSerializator(resultData), resultMemoryManager(resultData)
34 client = sphinx_create(SPH_TRUE);
44 sphinx_destroy(client);
45 cleanup(field_names, field_weights, fieldsCount);
46 cleanup(index_names, index_weights, indexesCount);
57 for (
size_t i=0;i<queryExtendedFields.size();++i)
69 for (
size_t i=0;i<schemaNames.size();++i)
94 std::stringstream outMsg, errMsg;
95 const std::string
cmd(
"searchd");
96 std::vector<std::string>
args = {
"--config", configFile};
98 procExec.
exec(outMsg, errMsg);
111 fObj.
log(LoggerStream::Priority::PRIO_INFORMATION) <<
".";
112 fObj.
log(LoggerStream::Priority::PRIO_INFORMATION).flush();
113 fObj.
log(LoggerStream::Priority::PRIO_INFORMATION) <<
flush;
128 catch(Poco::Exception& e)
140 errorMsg.append(
"\n").append(e.message());
158 std::stringstream outMsg, errMsg;
159 const std::string
cmd(
"searchd");
160 std::vector<std::string>
args = {
"--stop",
"--config", configFile};
162 if (!procExec.
exec(outMsg, errMsg))
169 catch(Poco::Exception& e)
184 if (indexStatusSearchd.
execute())
204 void SphinxSearcher::setLimits(
unsigned int offset,
unsigned int limit,
unsigned int maxMatches,
unsigned int cutoff)
throw (Poco::Exception)
209 if (!sphinx_set_limits(client, offset, limit, maxMatches, cutoff))
218 if (pFilter.isNull())
221 bool exclude = (pFilter->getExcludeValue()==SphinxFilter::ExcludeType::etTrue);
225 if (pFilter->getFilterType()==SphinxFilter::FilterType::ftSimple)
227 std::vector<long long> vFilters;
228 for (
size_t i=0;i<pFilter->getAttributeValues().size();++i)
229 vFilters.push_back(std::stoll(pFilter->getAttributeValues()[i]));
231 if (!
addFilter(pFilter->getAttributeName(), vFilters, exclude))
234 else if(pFilter->getFilterType()==SphinxFilter::FilterType::ftRangeInteger)
236 if (pFilter->getAttributeValues().size() < 2)
239 if (!addFilterRange(pFilter->getAttributeName(), std::stoull(pFilter->getAttributeValues()[0]), std::stoull(pFilter->getAttributeValues()[1]), exclude))
242 else if(pFilter->getFilterType()==SphinxFilter::FilterType::ftRangeFloat)
244 if (pFilter->getAttributeValues().size() < 2)
247 if (!addFilterFloatRange(pFilter->getAttributeName(), std::stof(pFilter->getAttributeValues()[0]), std::stof(pFilter->getAttributeValues()[1]), exclude))
250 else if(pFilter->getFilterType()==SphinxFilter::FilterType::ftSimpleMulti)
252 for (
size_t i=0;i<pFilter->getAttributeValues().size();++i)
254 if (!
addFilter(pFilter->getAttributeName(), std::stoull(pFilter->getAttributeValues()[i]), exclude))
261 catch(std::exception& e)
295 if (!sphinx_open(client))
309 catch(Poco::Exception& e)
338 if (!sphinx_open(client))
344 catch(Poco::Exception& e)
362 if (!sphinx_close(client))
368 catch(Poco::Exception& e)
381 for (
size_t i=0;i<count;++i)
403 cleanup(names, weights, count);
406 names =
new char*[count];
407 weights =
new int[count];
409 for (
size_t i=0;i<count;++i)
411 names[i] =
new char[Vec[i].first.length()+1];
412 memset(names[i], 0, Vec[i].first.length()+1);
413 memcpy(names[i], Vec[i].first.c_str(), Vec[i].first.length());
414 weights[i] = Vec[i].second;
425 if (
setWeights(field_names, field_weights, fieldsCount, Vec))
426 result = sphinx_set_field_weights(client, fieldsCount, (
const char**)field_names, field_weights);
438 if (
setWeights(index_names, index_weights, indexesCount, Vec))
439 result = sphinx_set_index_weights(client, indexesCount, (
const char**)index_names, index_weights);
453 for (
size_t i=0;i<count;++i)
455 if (names[i]!=
nullptr)
456 Vec.push_back(std::make_pair <std::string, int> (static_cast<std::string>(names[i]), static_cast<int>(weights[i])));
462 getWeights(field_names, field_weights, fieldsCount, Vec);
467 getWeights(index_names, index_weights, indexesCount, Vec);
470 std::vector <std::pair<std::string, int> >::iterator
SphinxSearcher::find(std::vector <std::pair<std::string, int> >& Vec,
const std::string&
name)
472 std::vector <std::pair<std::string, int> >::iterator iter;
473 for (iter=Vec.begin();iter!=Vec.end();++iter)
475 if ((*iter).first == name)
484 std::vector <std::pair<std::string, int> > Vec;
486 return (this->
find(Vec, name) != Vec.end());
492 std::vector <std::pair<std::string, int> > Vec;
494 return (this->
find(Vec, name) != Vec.end());
500 std::vector <std::pair<std::string, int> > Vec;
502 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
503 return (iter!=Vec.end())?(*iter).second:0;
509 std::vector <std::pair<std::string, int> > Vec;
511 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
512 return (iter!=Vec.end())?(*iter).second:0;
521 std::vector <std::pair<std::string, int> > Vec;
524 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
527 Vec.push_back(std::make_pair (name, weight));
542 std::vector <std::pair<std::string, int> > Vec;
545 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
563 std::vector <std::pair<std::string, int> > Vec;
566 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
584 std::vector <std::pair<std::string, int> > Vec;
587 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
590 Vec.push_back(std::make_pair (name, weight));
605 std::vector <std::pair<std::string, int> > Vec;
608 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
626 std::vector <std::pair<std::string, int> > Vec;
629 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
649 if (!sphinx_set_match_mode(client, mode))
654 catch(Poco::Exception& e)
672 if (!sphinx_set_sort_mode(client, SPH_SORT_RELEVANCE,
nullptr))
677 if (!sphinx_set_sort_mode(client, mode, sortby.c_str()))
682 catch(Poco::Exception& e)
698 if (rankexpr.empty())
700 if (!sphinx_set_ranking_mode(client, ranker,
nullptr))
705 if (!sphinx_set_ranking_mode(client, ranker, rankexpr.c_str()))
710 catch(Poco::Exception& e)
723 if (!sphinx_set_max_query_time(client, maxQueryTime))
730 for (
size_t i=0;i<indexesCount;++i)
732 if (indexFileName_ == index_names[i])
754 sphinx_result* res = 0;
755 int i, j, k, mva_len;
759 for (
size_t z=0;z<indexesCount;++z)
765 res = sphinx_query(client, query.c_str(),
indexName,
nullptr);
775 std::string warningMsg(sphinx_warning(client));
776 if (!warningMsg.empty())
787 for (i=0; i<res->num_words; ++i)
790 for (i=0; i<res->num_matches; ++i)
795 const std::string
sphinxWeight = std::to_string(sphinx_get_weight(res, i));
797 for (j=0; j<res->num_attrs; ++j)
801 std::stringstream valueStr;
803 switch(res->attr_types[j])
805 case SPH_ATTR_MULTI64:
807 mva = sphinx_get_mva(res, i, j);
809 for (k=0; k<mva_len; ++k)
810 valueStr << (res->attr_types[j]==SPH_ATTR_MULTI ? mva[k] : (
unsigned int)sphinx_get_mva64_value(mva, k));
812 case SPH_ATTR_FLOAT: valueStr << sphinx_get_float(res, i, j);
814 case SPH_ATTR_STRING: valueStr << sphinx_get_string(res, i, j);
816 default: valueStr << (sphinx_int64_t)sphinx_get_int(res, i, j);
862 return sphinx_add_filter(client, attrName.c_str(), 1, &value, exclude);
868 long long* pVal =
new long long[values.size()];
871 for (
size_t i=0;i<values.size();++i)
873 result = sphinx_add_filter(client, attrName.c_str(), values.size(), pVal, exclude);
881 return sphinx_add_filter_range(client, attrName.c_str(), umin, umax, exclude);
886 return sphinx_add_filter_float_range(client, attrName.c_str(), fmin, fmax, exclude);
891 sphinx_reset_filters(client);
900 timeval tvStart, tvStop;
901 gettimeofday(&tvStart, 0);
909 if (inputMessage.
getType() == SphinxInputJsonMessage::MessageType::mtSearch)
912 if (resultData.empty())
915 resultData = defaultJson.
getJSON();
921 catch(Poco::Exception& e)
928 resultData = defaultJson.
getJSON();
932 gettimeofday(&tvStop, 0);
937 outputMessage.
setData(resultData);
939 bool success = outputMessage.
serialize(resJson);
948 resultMemoryManager.reset();
950 resultData.clearRequestInfo();
960 unsigned int offsetResults = 0;
961 unsigned int limitResults = 0;
962 unsigned int cutoffResults = 0;
965 unsigned long long timeoutValue = defaultRequestTimeout;
969 std::string weightAlgirithm(
"");
982 resultSerializator.setJsonType(std::stoul(messageSearch.
getQueryParameters()[k].second,
nullptr, 0));
988 if (!sortFieldName.empty())
989 if (!isExistSchemaNames(sortFieldName))
997 if (!setSortMode(sortOrderBy, sortFieldName))
1016 catch(std::exception& e)
1033 catch(std::exception& e)
1039 catch(Poco::Exception& e)
1046 if (limitResults==0)
1049 setLimits(offsetResults, limitResults, maxResultsNumber, cutoffResults);
1057 setMaxQueryTime(timeoutValue);
1063 requestInfo.setMaxResultsNumber(maxResultsNumber);
1065 resultData.addRequestInfo(std::forward<SphinxRequestInfo>(
requestInfo));
1070 calculator.
calculate(orderFieldsNames, resultData);
1071 fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << calculator.
getLogString();
1073 std::string resultJson;
1074 if (!resultSerializator.serialize(resultJson, orderFieldsNames.size(), fObj.getMinNumberFieldsPacking()))
1086 timeval tvStart, tvStop;
1087 gettimeofday(&tvStart, 0);
1091 if (inputJsonMessage.
getType() != SphinxInputJsonMessage::MessageType::mtSearch)
1095 if (resultData.empty())
1098 resultData = defaultJson.
getJSON();
1101 catch(Poco::Exception& e)
1108 resultData = defaultJson.
getJSON();
1110 gettimeofday(&tvStop, 0);
1115 outputMessage.
setData(resultData);
1118 return outputMessage;