@@ -117,99 +117,148 @@ std::vector<std::wstring> LuceneGlobalIndexReader::TokenizeQuery(const std::stri
117117 return wterms;
118118}
119119
120+ Lucene::QueryPtr LuceneGlobalIndexReader::ConstructMatchQuery (
121+ const std::shared_ptr<FullTextSearch>& full_text_search) const {
122+ assert (full_text_search->search_type == FullTextSearch::SearchType::MATCH_ALL ||
123+ full_text_search->search_type == FullTextSearch::SearchType::MATCH_ANY );
124+ Lucene::BooleanClause::Occur occur =
125+ full_text_search->search_type == FullTextSearch::SearchType::MATCH_ALL
126+ ? Lucene::BooleanClause::Occur::MUST
127+ : Lucene::BooleanClause::Occur::SHOULD ;
128+ std::vector<std::wstring> query_terms = TokenizeQuery (full_text_search->query );
129+ if (query_terms.size () == 1 ) {
130+ return Lucene::newLucene<Lucene::TermQuery>(
131+ Lucene::newLucene<Lucene::Term>(wfield_name_, query_terms[0 ]));
132+ } else {
133+ auto typed_query = Lucene::newLucene<Lucene::BooleanQuery>();
134+ for (const auto & term : query_terms) {
135+ typed_query->add (Lucene::newLucene<Lucene::TermQuery>(
136+ Lucene::newLucene<Lucene::Term>(wfield_name_, term)),
137+ occur);
138+ }
139+ return typed_query;
140+ }
141+ }
142+
143+ Lucene::QueryPtr LuceneGlobalIndexReader::ConstructPhraseQuery (
144+ const std::shared_ptr<FullTextSearch>& full_text_search) const {
145+ assert (full_text_search->search_type == FullTextSearch::SearchType::PHRASE );
146+ std::vector<std::wstring> query_terms = TokenizeQuery (full_text_search->query );
147+ auto typed_query = Lucene::newLucene<Lucene::PhraseQuery>();
148+ for (const auto & term : query_terms) {
149+ typed_query->add (Lucene::newLucene<Lucene::Term>(wfield_name_, term));
150+ }
151+ return typed_query;
152+ }
153+
154+ Lucene::QueryPtr LuceneGlobalIndexReader::ConstructPrefixQuery (
155+ const std::shared_ptr<FullTextSearch>& full_text_search) const {
156+ assert (full_text_search->search_type == FullTextSearch::SearchType::PREFIX );
157+ return Lucene::newLucene<Lucene::PrefixQuery>(Lucene::newLucene<Lucene::Term>(
158+ wfield_name_, LuceneUtils::StringToWstring (full_text_search->query )));
159+ }
160+
161+ Lucene::QueryPtr LuceneGlobalIndexReader::ConstructWildCardQuery (
162+ const std::shared_ptr<FullTextSearch>& full_text_search) const {
163+ assert (full_text_search->search_type == FullTextSearch::SearchType::WILDCARD );
164+ return Lucene::newLucene<Lucene::WildcardQuery>(Lucene::newLucene<Lucene::Term>(
165+ wfield_name_, LuceneUtils::StringToWstring (full_text_search->query )));
166+ }
167+
168+ Result<std::shared_ptr<GlobalIndexResult>> LuceneGlobalIndexReader::SearchWithLimit (
169+ const Lucene::QueryPtr& query, const std::shared_ptr<FullTextSearch>& full_text_search) const {
170+ assert (full_text_search->limit );
171+ try {
172+ Lucene::FilterPtr filter =
173+ full_text_search->pre_filter
174+ ? Lucene::newLucene<LuceneFilter>(&(full_text_search->pre_filter .value ()))
175+ : Lucene::FilterPtr ();
176+
177+ Lucene::TopDocsPtr results =
178+ searcher_->search (query, filter, full_text_search->limit .value ());
179+
180+ // prepare BitmapVectorSearchGlobalIndexResult
181+ std::map<int64_t , float > id_to_score;
182+ for (auto score_doc : results->scoreDocs ) {
183+ Lucene::DocumentPtr result_doc = searcher_->doc (score_doc->doc );
184+ std::string row_id_str =
185+ LuceneUtils::WstringToString (result_doc->get (kRowIdFieldWstring ));
186+ std::optional<int32_t > row_id = StringUtils::StringToValue<int32_t >(row_id_str);
187+ if (!row_id) {
188+ return Status::Invalid (
189+ fmt::format (" parse row id str {} to int failed" , row_id_str));
190+ }
191+ id_to_score[static_cast <int64_t >(row_id.value ())] =
192+ static_cast <float >(score_doc->score );
193+ }
194+ RoaringBitmap64 bitmap;
195+ std::vector<float > scores;
196+ scores.reserve (id_to_score.size ());
197+ for (const auto & [id, score] : id_to_score) {
198+ bitmap.Add (id);
199+ scores.push_back (score);
200+ }
201+ return std::make_shared<BitmapVectorSearchGlobalIndexResult>(std::move (bitmap),
202+ std::move (scores));
203+ } catch (const std::exception& e) {
204+ return Status::Invalid (fmt::format (" visit term query failed, with {} error." , e.what ()));
205+ } catch (...) {
206+ return Status::UnknownError (" visit term query failed, with unknown error." );
207+ }
208+ }
209+
210+ Result<std::shared_ptr<GlobalIndexResult>> LuceneGlobalIndexReader::SearchWithNoLimit (
211+ const Lucene::QueryPtr& query, const std::shared_ptr<FullTextSearch>& full_text_search) const {
212+ assert (!full_text_search->limit );
213+ Lucene::FilterPtr filter =
214+ full_text_search->pre_filter
215+ ? Lucene::newLucene<LuceneFilter>(&(full_text_search->pre_filter .value ()))
216+ : Lucene::FilterPtr ();
217+
218+ // with no limit & no score
219+ auto collector = Lucene::newLucene<LuceneCollector>();
220+ searcher_->search (query, filter, collector);
221+ return std::make_shared<BitmapGlobalIndexResult>(
222+ [collector]() -> Result<RoaringBitmap64> { return collector->GetBitmap (); });
223+ }
224+
120225Result<std::shared_ptr<GlobalIndexResult>> LuceneGlobalIndexReader::VisitFullTextSearch (
121226 const std::shared_ptr<FullTextSearch>& full_text_search) {
122227 try {
123228 Lucene::QueryPtr query;
124229 switch (full_text_search->search_type ) {
125230 case FullTextSearch::SearchType::MATCH_ALL :
126231 case FullTextSearch::SearchType::MATCH_ANY : {
127- Lucene::BooleanClause::Occur occur =
128- full_text_search->search_type == FullTextSearch::SearchType::MATCH_ALL
129- ? Lucene::BooleanClause::Occur::MUST
130- : Lucene::BooleanClause::Occur::SHOULD ;
131- std::vector<std::wstring> query_terms = TokenizeQuery (full_text_search->query );
132- if (query_terms.size () == 1 ) {
133- query = Lucene::newLucene<Lucene::TermQuery>(
134- Lucene::newLucene<Lucene::Term>(wfield_name_, query_terms[0 ]));
135- } else {
136- auto typed_query = Lucene::newLucene<Lucene::BooleanQuery>();
137- for (const auto & term : query_terms) {
138- typed_query->add (Lucene::newLucene<Lucene::TermQuery>(
139- Lucene::newLucene<Lucene::Term>(wfield_name_, term)),
140- occur);
141- }
142- query = typed_query;
143- }
232+ query = ConstructMatchQuery (full_text_search);
144233 break ;
145234 }
146235 case FullTextSearch::SearchType::PHRASE : {
147- std::vector<std::wstring> query_terms = TokenizeQuery (full_text_search->query );
148- auto typed_query = Lucene::newLucene<Lucene::PhraseQuery>();
149- for (const auto & term : query_terms) {
150- typed_query->add (Lucene::newLucene<Lucene::Term>(wfield_name_, term));
151- }
152- query = typed_query;
236+ query = ConstructPhraseQuery (full_text_search);
153237 break ;
154238 }
155239 case FullTextSearch::SearchType::PREFIX : {
156- query = Lucene::newLucene<Lucene::PrefixQuery>(Lucene::newLucene<Lucene::Term>(
157- wfield_name_, LuceneUtils::StringToWstring (full_text_search->query )));
240+ query = ConstructPrefixQuery (full_text_search);
158241 break ;
159242 }
160243 case FullTextSearch::SearchType::WILDCARD : {
161- query = Lucene::newLucene<Lucene::WildcardQuery>(Lucene::newLucene<Lucene::Term>(
162- wfield_name_, LuceneUtils::StringToWstring (full_text_search->query )));
244+ query = ConstructWildCardQuery (full_text_search);
163245 break ;
164246 }
165247 default :
166248 return Status::Invalid (
167249 fmt::format (" Not support for FullTextSearch SearchType {}" ,
168250 static_cast <int32_t >(full_text_search->search_type )));
169251 }
170- Lucene::FilterPtr filter =
171- full_text_search->pre_filter
172- ? Lucene::newLucene<LuceneFilter>(&(full_text_search->pre_filter .value ()))
173- : Lucene::FilterPtr ();
174-
175252 if (full_text_search->limit ) {
176- Lucene::TopDocsPtr results =
177- searcher_->search (query, filter, full_text_search->limit .value ());
178-
179- // prepare BitmapVectorSearchGlobalIndexResult
180- std::map<int64_t , float > id_to_score;
181- for (auto score_doc : results->scoreDocs ) {
182- Lucene::DocumentPtr result_doc = searcher_->doc (score_doc->doc );
183- std::string row_id_str =
184- LuceneUtils::WstringToString (result_doc->get (kRowIdFieldWstring ));
185- std::optional<int32_t > row_id = StringUtils::StringToValue<int32_t >(row_id_str);
186- if (!row_id) {
187- return Status::Invalid (
188- fmt::format (" parse row id str {} to int failed" , row_id_str));
189- }
190- id_to_score[static_cast <int64_t >(row_id.value ())] =
191- static_cast <float >(score_doc->score );
192- }
193- RoaringBitmap64 bitmap;
194- std::vector<float > scores;
195- scores.reserve (id_to_score.size ());
196- for (const auto & [id, score] : id_to_score) {
197- bitmap.Add (id);
198- scores.push_back (score);
199- }
200- return std::make_shared<BitmapVectorSearchGlobalIndexResult>(std::move (bitmap),
201- std::move (scores));
253+ return SearchWithLimit (query, full_text_search);
202254 } else {
203- // with no limit & no score
204- auto collector = Lucene::newLucene<LuceneCollector>();
205- searcher_->search (query, filter, collector);
206- return std::make_shared<BitmapGlobalIndexResult>(
207- [collector]() -> Result<RoaringBitmap64> { return collector->GetBitmap (); });
255+ return SearchWithNoLimit (query, full_text_search);
208256 }
209257 } catch (const std::exception& e) {
210- return Status::Invalid (fmt::format (" visit term query failed, with {} error." , e.what ()));
258+ return Status::Invalid (
259+ fmt::format (" visit full text search failed, with {} error." , e.what ()));
211260 } catch (...) {
212- return Status::UnknownError (" visit term query failed, with unknown error." );
261+ return Status::UnknownError (" visit full text search failed, with unknown error." );
213262 }
214263}
215264
0 commit comments