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()),
30 serverHost(sphinx_search_const::
defaultHost), serverPort(sphinx_search_const::
defaultPort), indexFileName(
""),
31 _StopSearchd(stopSearchd_), _isConnected(false), 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);
127 catch(Poco::Exception& e)
139 errorMsg.append(
"\n").append(e.message());
160 std::stringstream outMsg, errMsg;
161 const std::string cmd(
"searchd");
162 std::vector<std::string> args = {
"--stop",
"--config", configFile};
164 if (!procExec.
exec(outMsg, errMsg))
182 catch(Poco::Exception& e)
197 if (indexStatusSearchd.
execute())
217 void SphinxSearcher::setLimits(
unsigned int offset,
unsigned int limit,
unsigned int maxMatches,
unsigned int cutoff)
throw (Poco::Exception)
222 if (!sphinx_set_limits(client, offset, limit, maxMatches, cutoff))
231 if (pFilter.isNull())
234 bool exclude = (pFilter->getExcludeValue()==SphinxFilter::ExcludeType::etTrue);
238 if (pFilter->getFilterType()==SphinxFilter::FilterType::ftSimple)
240 std::vector<long long> vFilters;
241 for (
size_t i=0;i<pFilter->getAttributeValues().size();++i)
242 vFilters.push_back(std::stoll(pFilter->getAttributeValues()[i]));
244 if (!
addFilter(pFilter->getAttributeName(), vFilters, exclude))
247 else if(pFilter->getFilterType()==SphinxFilter::FilterType::ftRangeInteger)
249 if (pFilter->getAttributeValues().size() < 2)
252 if (!addFilterRange(pFilter->getAttributeName(), std::stoull(pFilter->getAttributeValues()[0]), std::stoull(pFilter->getAttributeValues()[1]), exclude))
255 else if(pFilter->getFilterType()==SphinxFilter::FilterType::ftRangeFloat)
257 if (pFilter->getAttributeValues().size() < 2)
260 if (!addFilterFloatRange(pFilter->getAttributeName(), std::stof(pFilter->getAttributeValues()[0]), std::stof(pFilter->getAttributeValues()[1]), exclude))
263 else if(pFilter->getFilterType()==SphinxFilter::FilterType::ftSimpleMulti)
265 for (
size_t i=0;i<pFilter->getAttributeValues().size();++i)
267 if (!
addFilter(pFilter->getAttributeName(), std::stoull(pFilter->getAttributeValues()[i]), exclude))
274 catch(std::exception& e)
308 if (!sphinx_open(client))
322 catch(Poco::Exception& e)
351 if (!sphinx_open(client))
357 catch(Poco::Exception& e)
375 if (!sphinx_close(client))
381 catch(Poco::Exception& e)
394 for (
size_t i=0;i<count;++i)
416 cleanup(names, weights, count);
419 names =
new char*[count];
420 weights =
new int[count];
422 for (
size_t i=0;i<count;++i)
424 names[i] =
new char[Vec[i].first.length()+1];
425 memset(names[i], 0, Vec[i].first.length()+1);
426 memcpy(names[i], Vec[i].first.c_str(), Vec[i].first.length());
427 weights[i] = Vec[i].second;
438 if (
setWeights(field_names, field_weights, fieldsCount, Vec))
439 result = sphinx_set_field_weights(client, fieldsCount, (
const char**)field_names, field_weights);
451 if (
setWeights(index_names, index_weights, indexesCount, Vec))
452 result = sphinx_set_index_weights(client, indexesCount, (
const char**)index_names, index_weights);
466 for (
size_t i=0;i<count;++i)
468 if (names[i]!=
nullptr)
469 Vec.push_back(std::make_pair <std::string, int> (static_cast<std::string>(names[i]), static_cast<int>(weights[i])));
475 getWeights(field_names, field_weights, fieldsCount, Vec);
480 getWeights(index_names, index_weights, indexesCount, Vec);
483 std::vector <std::pair<std::string, int> >::iterator
SphinxSearcher::find(std::vector <std::pair<std::string, int> >& Vec,
const std::string& name)
485 std::vector <std::pair<std::string, int> >::iterator iter;
486 for (iter=Vec.begin();iter!=Vec.end();++iter)
488 if ((*iter).first == name)
497 std::vector <std::pair<std::string, int> > Vec;
499 return (this->
find(Vec, name) != Vec.end());
505 std::vector <std::pair<std::string, int> > Vec;
507 return (this->
find(Vec, name) != Vec.end());
513 std::vector <std::pair<std::string, int> > Vec;
515 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
516 return (iter!=Vec.end())?(*iter).second:0;
522 std::vector <std::pair<std::string, int> > Vec;
524 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
525 return (iter!=Vec.end())?(*iter).second:0;
534 std::vector <std::pair<std::string, int> > Vec;
537 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
540 Vec.push_back(std::make_pair (name, weight));
555 std::vector <std::pair<std::string, int> > Vec;
558 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
576 std::vector <std::pair<std::string, int> > Vec;
579 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
597 std::vector <std::pair<std::string, int> > Vec;
600 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
603 Vec.push_back(std::make_pair (name, weight));
618 std::vector <std::pair<std::string, int> > Vec;
621 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
639 std::vector <std::pair<std::string, int> > Vec;
642 std::vector <std::pair<std::string, int> >::iterator iter = this->
find(Vec, name);
662 if (!sphinx_set_match_mode(client, mode))
667 catch(Poco::Exception& e)
685 if (!sphinx_set_sort_mode(client, SPH_SORT_RELEVANCE,
nullptr))
690 if (!sphinx_set_sort_mode(client, mode, sortby.c_str()))
695 catch(Poco::Exception& e)
711 if (rankexpr.empty())
713 if (!sphinx_set_ranking_mode(client, ranker,
nullptr))
718 if (!sphinx_set_ranking_mode(client, ranker, rankexpr.c_str()))
723 catch(Poco::Exception& e)
736 if (!sphinx_set_max_query_time(client, maxQueryTime))
743 for (
size_t i=0;i<indexesCount;++i)
745 if (indexFileName_ == index_names[i])
767 sphinx_result* res = 0;
768 int i, j, k, mva_len;
772 for (
size_t z=0;z<indexesCount;++z)
778 res = sphinx_query(client, query.c_str(),
indexName,
nullptr);
788 std::string warningMsg(sphinx_warning(client));
789 if (!warningMsg.empty())
800 for (i=0; i<res->num_words; ++i)
803 for (i=0; i<res->num_matches; ++i)
808 const std::string
sphinxWeight = std::to_string(sphinx_get_weight(res, i));
810 for (j=0; j<res->num_attrs; ++j)
814 std::stringstream valueStr;
816 switch(res->attr_types[j])
818 case SPH_ATTR_MULTI64:
820 mva = sphinx_get_mva(res, i, j);
822 for (k=0; k<mva_len; ++k)
823 valueStr << (res->attr_types[j]==SPH_ATTR_MULTI ? mva[k] : (
unsigned int)sphinx_get_mva64_value(mva, k));
825 case SPH_ATTR_FLOAT: valueStr << sphinx_get_float(res, i, j);
827 case SPH_ATTR_STRING: valueStr << sphinx_get_string(res, i, j);
829 default: valueStr << (sphinx_int64_t)sphinx_get_int(res, i, j);
875 return sphinx_add_filter(client, attrName.c_str(), 1, &value, exclude);
881 long long* pVal =
new long long[values.size()];
884 for (
size_t i=0;i<values.size();++i)
886 result = sphinx_add_filter(client, attrName.c_str(), values.size(), pVal, exclude);
894 return sphinx_add_filter_range(client, attrName.c_str(), umin, umax, exclude);
899 return sphinx_add_filter_float_range(client, attrName.c_str(), fmin, fmax, exclude);
904 sphinx_reset_filters(client);
913 timeval tvStart, tvStop;
914 gettimeofday(&tvStart, 0);
922 if (inputMessage.
getType() == SphinxInputJsonMessage::MessageType::mtSearch)
925 if (resultData.empty())
928 resultData = defaultJson.
getJSON();
934 catch(Poco::Exception& e)
941 resultData = defaultJson.
getJSON();
945 gettimeofday(&tvStop, 0);
950 outputMessage.
setData(resultData);
952 bool success = outputMessage.
serialize(resJson);
961 resultMemoryManager.reset();
963 resultData.clearRequestInfo();
973 unsigned int offsetResults = 0;
974 unsigned int limitResults = 0;
975 unsigned int cutoffResults = 0;
978 unsigned long long timeoutValue = defaultRequestTimeout;
982 std::string weightAlgirithm(
"");
995 resultSerializator.setJsonType(std::stoul(messageSearch.
getQueryParameters()[k].second,
nullptr, 0));
1001 if (!sortFieldName.empty())
1002 if (!isExistSchemaNames(sortFieldName))
1010 if (!setSortMode(sortOrderBy, sortFieldName))
1029 catch(std::exception& e)
1046 catch(std::exception& e)
1052 catch(Poco::Exception& e)
1059 if (limitResults==0)
1062 setLimits(offsetResults, limitResults, maxResultsNumber, cutoffResults);
1070 setMaxQueryTime(timeoutValue);
1076 requestInfo.setMaxResultsNumber(maxResultsNumber);
1078 resultData.addRequestInfo(std::forward<SphinxRequestInfo>(
requestInfo));
1083 calculator.
calculate(orderFieldsNames, resultData);
1086 std::string resultJson;
1087 if (!resultSerializator.serialize(resultJson, orderFieldsNames.size(), fObj.getMinNumberFieldsPacking()))
1099 timeval tvStart, tvStop;
1100 gettimeofday(&tvStart, 0);
1104 if (inputJsonMessage.
getType() != SphinxInputJsonMessage::MessageType::mtSearch)
1108 if (resultData.empty())
1111 resultData = defaultJson.
getJSON();
1114 catch(Poco::Exception& e)
1121 resultData = defaultJson.
getJSON();
1123 gettimeofday(&tvStop, 0);
1128 outputMessage.
setData(resultData);
1131 return outputMessage;