|
From: Itamar Syn-H. <it...@di...> - 2009-05-05 06:04:37
|
Yes, files_list.txt.... > -----Original Message----- > From: Ben Van Klinken [mailto:bva...@gm...] > Sent: Tuesday, May 05, 2009 8:54 AM > To: syn...@us... > Cc: clu...@li... > Subject: Re: [Clucene-cvs] SF.net SVN: > clucene:[3006]branches/lucene2_3_2/src > > Looks like u might have got some binary data in your commit somehow. > Any idea what that is? Says "binary file a differ" > > B > > Verstuurd vanaf mijn iPhone > > Op 4 mei 2009 om 16:46 heeft syn...@us... > het volgende geschreven:\ > > > Revision: 3006 > > > http://clucene.svn.sourceforge.net/clucene/?rev=3006&view=rev > > Author: synhershko > > Date: 2009-05-04 14:46:40 +0000 (Mon, 04 May 2009) > > > > Log Message: > > ----------- > > MultiFieldQueryParser is back, now completely conforms with JL 2.3.2 > > > > Modified Paths: > > -------------- > > branches/lucene2_3_2/src/core/CLucene/files_list.txt > > branches/lucene2_3_2/src/core/CLucene/queryParser/ > > MultiFieldQueryParser.cpp > > branches/lucene2_3_2/src/core/CLucene/queryParser/ > > MultiFieldQueryParser.h > > branches/lucene2_3_2/src/core/CLucene/queryParser/QueryParser.h > > branches/lucene2_3_2/src/core/CMakeLists.txt > > branches/lucene2_3_2/src/test/queryParser/ > > TestMultiFieldQueryParser.cpp > > branches/lucene2_3_2/src/test/tests.cpp > > > > Modified: branches/lucene2_3_2/src/core/CLucene/files_list.txt > > =================================================================== > > (Binary files differ) > > > > Modified: branches/lucene2_3_2/src/core/CLucene/queryParser/ > > MultiFieldQueryParser.cpp > > =================================================================== > > --- branches/lucene2_3_2/src/core/CLucene/queryParser/ > > MultiFieldQueryParser.cpp 2009-05-03 21:01:38 UTC (rev 3005) > > +++ branches/lucene2_3_2/src/core/CLucene/queryParser/ > > MultiFieldQueryParser.cpp 2009-05-04 14:46:40 UTC (rev 3006) > > @@ -21,76 +21,18 @@ > > CL_NS_DEF(queryParser) > > > > > > -MultiFieldQueryParser::MultiFieldQueryParser(const TCHAR** fields, > > CL_NS(analysis)::Analyzer* a, BoostMap* boosts): > > - QueryParser(NULL,a) > > +MultiFieldQueryParser::MultiFieldQueryParser(const TCHAR** _fields, > > CL_NS(analysis)::Analyzer* a, BoostMap* _boosts): > > + QueryParser(NULL,a), fields(_fields), boosts(_boosts) > > { > > - this->fields = fields; > > - this->boosts = boosts; > > } > > MultiFieldQueryParser::~MultiFieldQueryParser(){ > > } > > > > -//static > > -Query* MultiFieldQueryParser::parse(const TCHAR* query, const > > TCHAR** fields, Analyzer* analyzer) > > -{ > > - BooleanQuery* bQuery = _CLNEW BooleanQuery( true ); > > - int32_t i = 0; > > - while ( fields[i] != NULL ){ > > - Query* q = QueryParser::parse(query, fields[i], analyzer); > > - if (q && (q->getQueryName()!=BooleanQuery::getClassName() > > || ((BooleanQuery*)q)->getClauseCount() > 0)) { > > - //todo: Move to using BooleanClause::Occur > > - bQuery->add(q, true, false, false); > > - } else { > > - _CLDELETE(q); > > - } > > - > > - i++; > > - } > > - return bQuery; > > -} > > - > > -//static > > -Query* MultiFieldQueryParser::parse(const TCHAR* query, const > > TCHAR** fields, const uint8_t* flags, Analyzer* analyzer) -{ > > - BooleanQuery* bQuery = _CLNEW BooleanQuery( true ); > > - int32_t i = 0; > > - while ( fields[i] != NULL ) > > - { > > - Query* q = QueryParser::parse(query, fields[i], analyzer); > > - if (q && (q->getQueryName()!=BooleanQuery::getClassName() > > || ((BooleanQuery*)q)->getClauseCount() > 0)) { > > - uint8_t flag = flags[i]; > > - switch (flag) > > - { > > - //todo: Move to using BooleanClause::Occur > > - case MultiFieldQueryParser::REQUIRED_FIELD: > > - bQuery->add(q, true, true, false); > > - break; > > - case MultiFieldQueryParser::PROHIBITED_FIELD: > > - bQuery->add(q, true, false, true); > > - break; > > - default: > > - bQuery->add(q, true, false, false); > > - break; > > - } > > - } else { > > - _CLDELETE(q); > > - } > > - > > - i++; > > - } > > - return bQuery; > > -} > > - > > -//not static > > -CL_NS(search)::Query* MultiFieldQueryParser::parse(const TCHAR* > > query) { > > - return parse(query, this->fields, this->analyzer); > > -} > > - > > -Query* MultiFieldQueryParser::GetFieldQuery(const TCHAR* field, > > TCHAR* queryText, int32_t slop){ > > +Query* MultiFieldQueryParser::getFieldQuery(const TCHAR* field, > > const TCHAR* queryText, const int32_t slop){ > > if (field == NULL) { > > vector<BooleanClause*> clauses; > > for (int i = 0; fields[i]!=NULL; ++i) { > > - Query* q = QueryParser::GetFieldQuery(fields[i], > > queryText); > > + Query* q = QueryParser::getFieldQuery(fields[i], > > queryText); > > if (q != NULL) { > > //If the user passes a map of boosts > > if (boosts != NULL) { > > @@ -103,116 +45,133 @@ > > if (q->getQueryName() == > PhraseQuery::getClassName()) { > > ((PhraseQuery*)q)->setSlop(slop); > > } > > + // TODO: > > //if (q instanceof MultiPhraseQuery) { > > // ((MultiPhraseQuery) q).setSlop(slop); > > //} > > - q = QueryAddedCallback(fields[i], q); > > - if ( q ) > > - clauses.push_back(_CLNEW > BooleanClause(q, true, > > false,false)); > > + clauses.push_back(_CLNEW BooleanClause(q, true, > > BooleanClause::SHOULD)); > > } > > } > > if (clauses.size() == 0) // happens for stopwords > > return NULL; > > - Query* q = QueryParser::GetBooleanQuery(clauses); > > - return q; > > + return QueryParser::getBooleanQuery(clauses, true); > > }else{ > > - Query* q = QueryParser::GetFieldQuery(field, queryText); > > - if ( q ) > > - q = QueryAddedCallback(field,q); > > - return q; > > + return QueryParser::getFieldQuery(field, queryText); > > } > > } > > > > - > > -Query* MultiFieldQueryParser::GetFieldQuery(const TCHAR* field, > > TCHAR* queryText){ > > - return GetFieldQuery(field, queryText, 0); > > -} > > - > > - > > -CL_NS(search)::Query* MultiFieldQueryParser::GetFuzzyQuery(const > > TCHAR* field, TCHAR* termStr){ > > +Query* MultiFieldQueryParser::getFuzzyQuery(const TCHAR* field, > > TCHAR* termStr, const float_t minSimilarity){ > > if (field == NULL) { > > vector<BooleanClause*> clauses; > > for (int i = 0; fields[i]!=NULL; ++i) { > > - Query* q = QueryParser::GetFuzzyQuery(fields[i], > > termStr); //todo: , minSimilarity > > - if ( q ){ > > - q = QueryAddedCallback(fields[i], q); > > - if ( q ){ > > - clauses.push_back(_CLNEW > > BooleanClause(q,true,false,false) ); > > - } > > - } > > + Query* q = QueryParser::getFuzzyQuery(fields[i], > > termStr, minSimilarity); > > + if (q) clauses.push_back(_CLNEW BooleanClause(q,true, > > BooleanClause::SHOULD) ); > > } > > - return QueryParser::GetBooleanQuery(clauses); > > - }else{ > > - Query* q = QueryParser::GetFuzzyQuery(field, termStr);// > > todo: , minSimilarity > > - if ( q ) > > - q = QueryAddedCallback(field,q); > > - return q; > > + return QueryParser::getBooleanQuery(clauses, true); > > } > > + return QueryParser::getFuzzyQuery(field, termStr, > minSimilarity); > > } > > > > -Query* MultiFieldQueryParser::GetPrefixQuery(const TCHAR* field, > > TCHAR* termStr){ > > +Query* MultiFieldQueryParser::getPrefixQuery(const TCHAR* field, > > TCHAR* termStr){ > > if (field == NULL) { > > vector<BooleanClause*> clauses; > > for (int i = 0; fields[i]!=NULL; ++i) { > > - Query* q = QueryParser::GetPrefixQuery(fields[i], > > termStr); > > - if ( q ){ > > - q = QueryAddedCallback(fields[i],q); > > - if ( q ){ > > - clauses.push_back(_CLNEW > > BooleanClause(q,true,false,false)); > > - } > > - } > > + Query* q = QueryParser::getPrefixQuery(fields[i], > > termStr); > > + if (q) clauses.push_back(_CLNEW > > BooleanClause(q,true,BooleanClause::SHOULD)); > > } > > - return QueryParser::GetBooleanQuery(clauses); > > - }else{ > > - Query* q = QueryParser::GetPrefixQuery(field, termStr); > > - if ( q ) > > - q = QueryAddedCallback(field,q); > > - return q; > > + return QueryParser::getBooleanQuery(clauses, true); > > } > > + return QueryParser::getPrefixQuery(field, termStr); > > } > > > > -Query* MultiFieldQueryParser::GetWildcardQuery(const TCHAR* field, > > TCHAR* termStr){ > > +Query* MultiFieldQueryParser::getWildcardQuery(const TCHAR* field, > > TCHAR* termStr){ > > if (field == NULL) { > > vector<BooleanClause*> clauses; > > for (int i = 0; fields[i]!=NULL; ++i) { > > - Query* q = QueryParser::GetWildcardQuery(fields[i], > > termStr); > > - if ( q ){ > > - q = QueryAddedCallback(fields[i],q); > > - if ( q ){ > > - clauses.push_back(_CLNEW > > BooleanClause(q,true,false,false)); > > - } > > - } > > + Query* q = QueryParser::getWildcardQuery(fields[i], > > termStr); > > + if (q) clauses.push_back(_CLNEW > > BooleanClause(q,true,BooleanClause::SHOULD)); > > } > > - return QueryParser::GetBooleanQuery(clauses); > > - }else{ > > - Query* q = QueryParser::GetWildcardQuery(field, termStr); > > - if ( q ) > > - q = QueryAddedCallback(field,q); > > - return q; > > + return QueryParser::getBooleanQuery(clauses, true); > > } > > + return QueryParser::getWildcardQuery(field, termStr); > > } > > > > > > -Query* MultiFieldQueryParser::GetRangeQuery(const TCHAR* field, > > TCHAR* part1, TCHAR* part2, bool inclusive){ > > +Query* MultiFieldQueryParser::getRangeQuery(const TCHAR* field, > > TCHAR* part1, TCHAR* part2, const bool inclusive){ > > if (field == NULL) { > > vector<BooleanClause*> clauses; > > for (int i = 0; fields[i]!=NULL; ++i) { > > - Query* q = > QueryParser::GetRangeQuery(fields[i], part1, > > part2, inclusive); > > - if ( q ){ > > - q = QueryAddedCallback(fields[i],q); > > - if ( q ){ > > - clauses.push_back(_CLNEW > > BooleanClause(q,true,false,false)); > > - } > > - } > > + Query* q = QueryParser::getRangeQuery(fields[i], part1, > > part2, inclusive); > > + if (q) clauses.push_back(_CLNEW > > BooleanClause(q,true,BooleanClause::SHOULD)); > > } > > - return QueryParser::GetBooleanQuery(clauses); > > + return QueryParser::getBooleanQuery(clauses, true); > > }else{ > > - Query* q = QueryParser::GetRangeQuery(field, > part1, part2, > > inclusive); > > - if ( q ) > > - q = QueryAddedCallback(field,q); > > - return q; > > + return QueryParser::getRangeQuery(field, part1, part2, > > inclusive); > > } > > } > > > > +//static > > +Query* MultiFieldQueryParser::parse(const TCHAR** _queries, const > > TCHAR** _fields, Analyzer* analyzer) > > +{ > > + BooleanQuery* bQuery = _CLNEW BooleanQuery(); > > + for (size_t i = 0; _fields[i]!=NULL; i++) > > + { > > + if (_queries[i] == NULL) { > > + _CLLDELETE(bQuery); > > + _CLTHROWA(CL_ERR_IllegalArgument, "_queries.length != > > _fields.length"); > > + } > > + // TODO: Reuse qp instead of creating it over and > over again > > + QueryParser* qp = _CLNEW QueryParser(_fields[i], analyzer); > > + Query* q = qp->parse(_queries[i]); > > + if (q!=NULL && // q never null, just being defensive > > + (!(q->instanceOf(BooleanQuery::getClassName()) || > > ((BooleanQuery*)q)->getClauseCount() > 0))) { > > + bQuery->add(q, true, BooleanClause::SHOULD); > > + } else > > + _CLLDELETE(q); > > + _CLLDELETE(qp); > > + } > > + return bQuery; > > +} > > > > +// static > > +Query* MultiFieldQueryParser::parse(const TCHAR* query, const > > TCHAR** _fields, const uint8_t* flags, Analyzer* analyzer) { > > + BooleanQuery* bQuery = _CLNEW BooleanQuery(); > > + for (size_t i = 0; _fields[i]!=NULL; i++) { > > + if (flags[i] == NULL) { > > + _CLLDELETE(bQuery); > > + _CLTHROWA(CL_ERR_IllegalArgument, "_fields.length != > > flags.length"); > > + } > > + QueryParser* qp = _CLNEW QueryParser(_fields[i], analyzer); > > + Query* q = qp->parse(query); > > + if (q!=NULL && // q never null, just being defensive > > + (!(q->instanceOf(BooleanQuery::getClassName())) || > > ((BooleanQuery*)q)->getClauseCount()>0)) { > > + bQuery->add(q, true, > (BooleanClause::Occur)flags[i]); > > + } else > > + _CLLDELETE(q); > > + _CLLDELETE(qp); > > + } > > + return bQuery; > > +} > > + > > +//static > > +Query* MultiFieldQueryParser::parse(const TCHAR** _queries, const > > TCHAR** _fields, const uint8_t* flags, Analyzer* analyzer){ > > + BooleanQuery* bQuery = _CLNEW BooleanQuery(); > > + for (size_t i = 0; _fields[i]!=NULL; i++) > > + { > > + if (_queries[i] == NULL || flags[i] == NULL) { > > + _CLLDELETE(bQuery); > > + _CLTHROWA(CL_ERR_IllegalArgument, "_queries, _fields, > > and flags array have have different length"); > > + } > > + QueryParser* qp = _CLNEW QueryParser(_fields[i], analyzer); > > + Query* q = qp->parse(_queries[i]); > > + if (q!=NULL && // q never null, just being defensive > > + (!(q->instanceOf(BooleanQuery::getClassName())) || > > ((BooleanQuery*)q)->getClauseCount()>0)) { > > + bQuery->add(q, true, > (BooleanClause::Occur)flags[i]); > > + } else > > + _CLLDELETE(q); > > + _CLLDELETE(qp); > > + } > > + return bQuery; > > +} > > + > > CL_NS_END > > > > Modified: branches/lucene2_3_2/src/core/CLucene/queryParser/ > > MultiFieldQueryParser.h > > =================================================================== > > --- branches/lucene2_3_2/src/core/CLucene/queryParser/ > > MultiFieldQueryParser.h 2009-05-03 21:01:38 UTC (rev 3005) > > +++ branches/lucene2_3_2/src/core/CLucene/queryParser/ > > MultiFieldQueryParser.h 2009-05-04 14:46:40 UTC (rev 3006) > > @@ -24,112 +24,142 @@ > > CL_NS(util)::Deletor::DummyFloat > >> BoostMap; > > > > - /** > > - * A QueryParser which constructs queries to search multiple > > fields. > > - * > > - */ > > - class CLUCENE_EXPORT MultiFieldQueryParser: public QueryParser > > - { > > - protected: > > - const TCHAR** fields; > > - BoostMap* boosts; > > - public: > > - LUCENE_STATIC_CONSTANT(uint8_t, NORMAL_FIELD=0); > > - LUCENE_STATIC_CONSTANT(uint8_t, REQUIRED_FIELD=1); > > - LUCENE_STATIC_CONSTANT(uint8_t, PROHIBITED_FIELD=2); > > - > > - /** > > - * Creates a MultiFieldQueryParser. > > - * > > - * <p>It will, when parse(String query) > > - * is called, construct a query like this (assuming the > > query consists of > > - * two terms and you specify the two fields <code>title</ > > code> and <code>body</code>):</p> > > - * > > - * <code> > > - * (title:term1 body:term1) (title:term2 body:term2) > > - * </code> > > - * > > - * <p>When setDefaultOperator(AND_OPERATOR) is set, the > > result will be:</p> > > - * > > - * <code> > > - * +(title:term1 body:term1) +(title:term2 body:term2) > > - * </code> > > - * > > - * <p>In other words, all the query's terms must > appear, but > > it doesn't matter in > > - * what fields they appear.</p> > > - */ > > - MultiFieldQueryParser(const TCHAR** fields, > > CL_NS(analysis)::Analyzer* a, BoostMap* boosts = NULL); > > - virtual ~MultiFieldQueryParser(); > > - > > - /** > > - * <p> > > - * Parses a query which searches on the fields specified. > > - * <p> > > - * If x fields are specified, this effectively constructs: > > - * <pre> > > - * <code> > > - * (field1:query) (field2:query) (field3:query)... > > (fieldx:query) > > - * </code> > > - * </pre> > > - * > > - * @param query Query string to parse > > - * @param fields Fields to search on > > - * @param analyzer Analyzer to use > > - * @throws ParserException if query parsing fails > > - * @throws TokenMgrError if query parsing fails > > - */ > > - static CL_NS(search)::Query* parse(const TCHAR* query, > > const TCHAR** fields, CL_NS(analysis)::Analyzer* analyzer); > > - > > - /** > > - * <p> > > - * Parses a query, searching on the fields specified. > > - * Use this if you need to specify certain fields as > > required, > > - * and others as prohibited. > > - * <p><pre> > > - * Usage: > > - * <code> > > - * TCHAR** fields = {"filename", "contents", > "description"}; > > - * int8_t* flags = {MultiFieldQueryParser::NORMAL FIELD, > > - * MultiFieldQueryParser::REQUIRED FIELD, > > - * MultiFieldQueryParser::PROHIBITED FIELD}; > > - * parse(query, fields, flags, analyzer); > > - * </code> > > - * </pre> > > - *<p> > > - * The code above would construct a query: > > - * <pre> > > - * <code> > > - * (filename:query) +(contents:query) -(description:query) > > - * </code> > > - * </pre> > > - * > > - * @param query Query string to parse > > - * @param fields Fields to search on > > - * @param flags Flags describing the fields > > - * @param analyzer Analyzer to use > > - * @throws ParserException if query parsing fails > > - * @throws TokenMgrError if query parsing fails > > - */ > > - static CL_NS(search)::Query* parse(const TCHAR* query, > > const TCHAR** fields, const uint8_t* flags, > > CL_NS(analysis)::Analyzer* analyzer); > > +/** > > +* A QueryParser which constructs queries to search multiple fields. > > +* > > +*/ > > +class CLUCENE_EXPORT MultiFieldQueryParser: public QueryParser { > > +protected: > > + const TCHAR** fields; > > + BoostMap* boosts; > > +public: > > + /** > > + * Creates a MultiFieldQueryParser. > > + * Allows passing of a map with term to Boost, and the boost to > > apply to each term. > > + * > > + * <p>It will, when parse(String query) > > + * is called, construct a query like this (assuming the query > > consists of > > + * two terms and you specify the two fields <code>title</code> > > and <code>body</code>):</p> > > + * > > + * <code> > > + * (title:term1 body:term1) (title:term2 body:term2) > > + * </code> > > + * > > + * <p>When setDefaultOperator(AND_OPERATOR) is set, the result > > will be:</p> > > + * > > + * <code> > > + * +(title:term1 body:term1) +(title:term2 body:term2) > > + * </code> > > + * > > + * <p>When you pass a boost (title=>5 body=>10) you can get </p> > > + * > > + * <code> > > + * +(title:term1^5.0 body:term1^10.0) +(title:term2^5.0 > > body:term2^10.0) > > + * </code> > > + * > > + * <p>In other words, all the query's terms must appear, but it > > doesn't matter in > > + * what fields they appear.</p> > > + */ > > + MultiFieldQueryParser(const TCHAR** _fields, > > CL_NS(analysis)::Analyzer* a, BoostMap* _boosts = NULL); > > + virtual ~MultiFieldQueryParser(); > > > > - // non-static version of the above > > - CL_NS(search)::Query* parse(const TCHAR* query); > > +protected: > > + CL_NS(search)::Query* getFieldQuery(const TCHAR* field, const > > TCHAR* queryText, const int32_t slop); > > + CL_NS(search)::Query* getFieldQuery(const TCHAR* field, const > > TCHAR* queryText) { return getFieldQuery(field,queryText,0); } > > + CL_NS(search)::Query* getFuzzyQuery(const TCHAR* field, TCHAR* > > termStr, const float_t minSimilarity); > > + CL_NS(search)::Query* getPrefixQuery(const TCHAR* field, TCHAR* > > termStr); > > + CL_NS(search)::Query* getWildcardQuery(const TCHAR* field, > > TCHAR* termStr); > > + CL_NS(search)::Query* getRangeQuery(const TCHAR* field, TCHAR* > > part1, TCHAR* part2, const bool inclusive); > > > > - protected: > > - CL_NS(search)::Query* GetFieldQuery(const TCHAR* field, > > TCHAR* queryText); > > - CL_NS(search)::Query* GetFieldQuery(const TCHAR* field, > > TCHAR* queryText, int32_t slop); > > - CL_NS(search)::Query* GetFuzzyQuery(const TCHAR* field, > > TCHAR* termStr); > > - CL_NS(search)::Query* GetRangeQuery(const TCHAR* field, > > TCHAR* part1, TCHAR* part2, bool inclusive); > > - CL_NS(search)::Query* GetPrefixQuery(const TCHAR* field, > > TCHAR* termStr); > > - CL_NS(search)::Query* GetWildcardQuery(const > TCHAR* field, > > TCHAR* termStr); > > +public: > > + /** > > + * Parses a query which searches on the fields specified. > > + * <p> > > + * If x fields are specified, this effectively constructs: > > + * <pre> > > + * <code> > > + * (field1:query1) (field2:query2) (field3:query3)... > > (fieldx:queryx) > > + * </code> > > + * </pre> > > + * @param queries Queries strings to parse > > + * @param fields Fields to search on > > + * @param analyzer Analyzer to use > > + * @throws ParseException if query parsing fails > > + * @throws IllegalArgumentException if the length of > the queries > > array differs > > + * from the length of the fields array > > + */ > > + static CL_NS(search)::Query* parse(const TCHAR** _queries, > > const TCHAR** _fields, > > + CL_NS(analysis)::Analyzer* analyzer); > > > > - /** > > - * A special virtual function for the > MultiFieldQueryParser > > which can be used > > - * to clean up queries. Once the field name is > known and the > > query has been > > - * created, its passed to this function. > > - * An example of this usage is to set boosts. > > - */ > > - virtual CL_NS(search)::Query* QueryAddedCallback(const > > TCHAR* field, CL_NS(search)::Query* query){ return query; } > > - }; > > + /** > > + * Parses a query, searching on the fields specified. > > + * Use this if you need to specify certain fields as required, > > + * and others as prohibited. > > + * <p><pre> > > + * Usage: > > + * <code> > > + * String[] fields = {"filename", "contents", "description"}; > > + * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD, > > + * BooleanClause.Occur.MUST, > > + * BooleanClause.Occur.MUST_NOT}; > > + * MultiFieldQueryParser.parse("query", fields, flags, > analyzer); > > + * </code> > > + * </pre> > > + *<p> > > + * The code above would construct a query: > > + * <pre> > > + * <code> > > + * (filename:query) +(contents:query) -(description:query) > > + * </code> > > + * </pre> > > + * > > + * @param query Query string to parse > > + * @param fields Fields to search on > > + * @param flags Flags describing the fields > > + * @param analyzer Analyzer to use > > + * @throws ParseException if query parsing fails > > + * @throws IllegalArgumentException if the length of > the fields > > array differs > > + * from the length of the flags array > > + */ > > + static CL_NS(search)::Query* parse(const TCHAR* query, const > > TCHAR** _fields, > > + const uint8_t* flags, CL_NS(analysis)::Analyzer* analyzer); > > + > > + /** > > + * Parses a query, searching on the fields specified. > > + * Use this if you need to specify certain fields as required, > > + * and others as prohibited. > > + * <p><pre> > > + * Usage: > > + * <code> > > + * String[] query = {"query1", "query2", "query3"}; > > + * String[] fields = {"filename", "contents", "description"}; > > + * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD, > > + * BooleanClause.Occur.MUST, > > + * BooleanClause.Occur.MUST_NOT}; > > + * MultiFieldQueryParser.parse(query, fields, flags, analyzer); > > + * </code> > > + * </pre> > > + *<p> > > + * The code above would construct a query: > > + * <pre> > > + * <code> > > + * (filename:query1) +(contents:query2) -(description:query3) > > + * </code> > > + * </pre> > > + * > > + * @param queries Queries string to parse > > + * @param fields Fields to search on > > + * @param flags Flags describing the fields > > + * @param analyzer Analyzer to use > > + * @throws ParseException if query parsing fails > > + * @throws IllegalArgumentException if the length of the > > queries, fields, > > + * and flags array differ > > + */ > > + static CL_NS(search)::Query* parse(const TCHAR** _queries, > > const TCHAR** _fields, const uint8_t* flags, > > + CL_NS(analysis)::Analyzer* analyzer); > > + > > + CL_NS(search)::Query* parse(const TCHAR* _query){return > > QueryParser::parse(_query);} > > +}; > > CL_NS_END > > #endif > > > > Modified: branches/lucene2_3_2/src/core/CLucene/queryParser/ > > QueryParser.h > > =================================================================== > > --- branches/lucene2_3_2/src/core/CLucene/queryParser/ > > QueryParser.h 2009-05-03 21:01:38 UTC (rev 3005) > > +++ branches/lucene2_3_2/src/core/CLucene/queryParser/ > > QueryParser.h 2009-05-04 14:46:40 UTC (rev 3006) > > @@ -322,7 +322,7 @@ > > /** > > * @exception ParseException throw in overridden method > to disallow > > */ > > - CL_NS(search)::Query* getFieldQuery(const TCHAR* > _field, const > > TCHAR* queryText); > > + virtual CL_NS(search)::Query* getFieldQuery(const TCHAR* > > _field, const TCHAR* queryText); > > > > /** > > * Base implementation delegates to {@link > > #getFieldQuery(String,String)}. > > @@ -331,12 +331,12 @@ > > * > > * @exception ParseException throw in overridden method > to disallow > > */ > > - CL_NS(search)::Query* getFieldQuery(const TCHAR* > _field, const > > TCHAR* queryText, const int32_t slop); > > + virtual CL_NS(search)::Query* getFieldQuery(const TCHAR* > > _field, const TCHAR* queryText, const int32_t slop); > > > > /** > > * @exception ParseException throw in overridden method > to disallow > > */ > > - CL_NS(search)::Query* getRangeQuery(const TCHAR* > field, TCHAR* > > part1, TCHAR* part2, const bool inclusive); > > + virtual CL_NS(search)::Query* getRangeQuery(const > TCHAR* field, > > TCHAR* part1, TCHAR* part2, const bool inclusive); > > > > /** > > * Factory method for generating query, given a set of clauses. > > @@ -375,7 +375,7 @@ > > * @return Resulting {@link Query} built for the term > > * @exception ParseException throw in overridden method > to disallow > > */ > > - CL_NS(search)::Query* getWildcardQuery(const TCHAR* _field, > > TCHAR* termStr); > > + virtual CL_NS(search)::Query* getWildcardQuery(const TCHAR* > > _field, TCHAR* termStr); > > > > /** > > * Factory method for generating a query (similar to > > @@ -400,7 +400,7 @@ > > * @return Resulting {@link Query} built for the term > > * @exception ParseException throw in overridden method > to disallow > > */ > > - CL_NS(search)::Query* getPrefixQuery(const TCHAR* _field, > > TCHAR* _termStr); > > + virtual CL_NS(search)::Query* getPrefixQuery(const TCHAR* > > _field, TCHAR* _termStr); > > > > /** > > * Factory method for generating a query (similar to > > @@ -413,7 +413,7 @@ > > * @return Resulting {@link Query} built for the term > > * @exception ParseException throw in overridden method > to disallow > > */ > > - CL_NS(search)::Query* getFuzzyQuery(const TCHAR* > _field, TCHAR* > > termStr, const float_t minSimilarity); > > + virtual CL_NS(search)::Query* getFuzzyQuery(const TCHAR* > > _field, TCHAR* termStr, const float_t minSimilarity); > > > > private: > > /** > > > > Modified: branches/lucene2_3_2/src/core/CMakeLists.txt > > =================================================================== > > --- branches/lucene2_3_2/src/core/CMakeLists.txt 2009-05-03 > > 21:01:38 UTC (rev 3005) > > +++ branches/lucene2_3_2/src/core/CMakeLists.txt 2009-05-04 > > 14:46:40 UTC (rev 3006) > > @@ -29,7 +29,7 @@ > > ./CLucene/util/StringIntern.cpp > > ./CLucene/util/BitSet.cpp > > ./CLucene/queryParser/FastCharStream.cpp > > - #./CLucene/queryParser/MultiFieldQueryParser.cpp > > + ./CLucene/queryParser/MultiFieldQueryParser.cpp > > ./CLucene/queryParser/QueryParser.cpp > > ./CLucene/queryParser/QueryParserTokenManager.cpp > > ./CLucene/queryParser/Token.cpp > > > > Modified: branches/lucene2_3_2/src/test/queryParser/ > > TestMultiFieldQueryParser.cpp > > =================================================================== > > --- branches/lucene2_3_2/src/test/queryParser/ > > TestMultiFieldQueryParser.cpp 2009-05-03 21:01:38 UTC (rev 3005) > > +++ branches/lucene2_3_2/src/test/queryParser/ > > TestMultiFieldQueryParser.cpp 2009-05-04 14:46:40 UTC (rev 3006) > > @@ -6,164 +6,167 @@ > > --- > > --- > > --- > > > --------------------------------------------------------------------- > > */ > > #include "test.h" > > > > -//class MQPTestFilter: public TokenFilter { > > -//public: > > -// > > -// bool inPhrase; > > -// int32_t savedStart, savedEnd; > > -// > > -// /** > > -// * Filter which discards the token 'stop' and which > expands the > > -// * token 'phrase' into 'phrase1 phrase2' > > -// */ > > -// MQPTestFilter(TokenStream* in): > > -// TokenFilter(in,true), > > -// inPhrase(false), > > -// savedStart(0), > > -// savedEnd(0) > > -// { > > -// } > > -// > > -// bool next(CL_NS(analysis)::Token* token) { > > -// if (inPhrase) { > > -// inPhrase = false; > > -// token->set( _T("phrase2"), savedStart, savedEnd); > > -// return true; > > -// }else{ > > -// while( input->next(token) ){ > > -// if ( _tcscmp(token->termBuffer(), _T("phrase")) > > == 0 ) { > > -// inPhrase = true; > > -// savedStart = token->startOffset(); > > -// savedEnd = token->endOffset(); > > -// token->set( _T("phrase1"), savedStart, > > savedEnd); > > -// return true; > > -// }else if ( _tcscmp(token->termBuffer(), > > _T("stop") ) !=0 ){ > > -// return true; > > -// } > > -// } > > -// } > > -// return false; > > -// } > > -//}; > > -// > > -//class MQPTestAnalyzer: public Analyzer { > > -//public: > > -// MQPTestAnalyzer() { > > -// } > > -// > > -// /** Filters LowerCaseTokenizer with StopFilter. */ > > -// TokenStream* tokenStream(const TCHAR* fieldName, Reader* > > reader) { > > -// return _CLNEW MQPTestFilter(_CLNEW > > LowerCaseTokenizer(reader)); > > -// } > > -//}; > > -// > > -//void assertEquals(CuTest *tc,const TCHAR* result, Query* q) { > > -// if ( q == NULL ) > > -// return; > > -// > > -// const TCHAR* s = q->toString(); > > -// int ret = _tcscmp(s,result); > > -// _CLDELETE(q); > > -// if ( ret != 0 ) { > > -// TCHAR buf[HUGE_STRING_LEN]; > > -// _sntprintf(buf, HUGE_STRING_LEN, _T("FAILED Query > > yielded /%s/, expecting /%s/\n"), s, result); > > -// _CLDELETE_LCARRAY(s); > > -// CuFail(tc, buf); > > -// } > > -// _CLDELETE_LCARRAY(s); > > -//} > > -// > > -//// verify parsing of query using a stopping analyzer > > -//void assertStopQueryEquals(CuTest *tc, const TCHAR* qtxt, const > > TCHAR* expectedRes) { > > -// const TCHAR* fields[] = {_T("b"), _T("t"), NULL }; > > -// //Occur occur[] = {Occur.SHOULD, Occur.SHOULD}; > > -// MQPTestAnalyzer *a = _CLNEW MQPTestAnalyzer(); > > -// MultiFieldQueryParser mfqp(fields, a); > > -// > > -// Query *q = mfqp.parse(qtxt); > > -// assertEquals(tc, expectedRes, q); > > -// > > -// q = MultiFieldQueryParser::parse(qtxt, fields, a); > > -// assertEquals(tc, expectedRes, q); > > -// _CLDELETE(a); > > -//} > > -// > > -///** test stop words arsing for both the non static form, > and for > > the > > -//* corresponding static form (qtxt, fields[]). */ > > -//void tesStopwordsParsing(CuTest *tc) { > > -// assertStopQueryEquals(tc, _T("one"), _T("b:one t:one")); > > -// assertStopQueryEquals(tc, _T("one stop"), _T("b:one t:one")); > > -// assertStopQueryEquals(tc, _T("one (stop)"), > _T("b:one t:one")); > > -// assertStopQueryEquals(tc, _T("one ((stop))"), _T("b:one > > t:one")); > > -// assertStopQueryEquals(tc, _T("stop"), _T("")); > > -// assertStopQueryEquals(tc, _T("(stop)"), _T("")); > > -// assertStopQueryEquals(tc, _T("((stop))"), _T("")); > > -//} > > -// > > -//void testMFQPSimple(CuTest *tc) { > > -// const TCHAR* fields[] = {_T("b"), _T("t"), NULL}; > > -// Analyzer* a = _CLNEW StandardAnalyzer(); > > -// MultiFieldQueryParser mfqp(fields, a); > > -// > > -// Query *q = mfqp.parse(_T("one")); > > -// assertEquals(tc, _T("b:one t:one"), q); > > -// > > -// q = mfqp.parse(_T("one two")); > > -// assertEquals(tc, _T("(b:one t:one) (b:two t:two)"),q); > > -// > > -// q = mfqp.parse(_T("+one +two")); > > -// assertEquals(tc, _T("+(b:one t:one) +(b:two t:two)"), q); > > -// > > -// q = mfqp.parse(_T("+one -two -three")); > > -// assertEquals(tc, _T("+(b:one t:one) -(b:two t:two) > -(b:three > > t:three)"), q); > > -// > > -// q = mfqp.parse(_T("one^2 two")); > > -// assertEquals(tc, _T("((b:one t:one)^2.0) (b:two t:two)"), q); > > -// > > -// q = mfqp.parse(_T("one~ two")); > > -// assertEquals(tc, _T("(b:one~0.5 t:one~0.5) (b:two > t:two)"), q); > > -// > > -// q = mfqp.parse(_T("one~0.8 two^2")); > > -// assertEquals(tc, _T("(b:one~0.8 t:one~0.8) ((b:two > > t:two)^2.0)"), q); > > -// > > -// q = mfqp.parse(_T("one* two*")); > > -// assertEquals(tc, _T("(b:one* t:one*) (b:two* t:two*)"), q); > > -// > > -// q = mfqp.parse(_T("[a TO c] two")); > > -// assertEquals(tc, _T("(b:[a TO c] t:[a TO c]) (b:two > t:two)"), > > q); > > -// > > -// q = mfqp.parse(_T("w?ldcard")); > > -// assertEquals(tc, _T("b:w?ldcard t:w?ldcard"), q); > > -// > > -// q = mfqp.parse(_T("\"foo bar\"")); > > -// assertEquals(tc, _T("b:\"foo bar\" t:\"foo bar\""), q); > > -// > > -// q = mfqp.parse(_T("\"aa bb cc\" \"dd ee\"")); > > -// assertEquals(tc, _T("(b:\"aa bb cc\" t:\"aa bb cc\") > (b:\"dd > > ee\" t:\"dd ee\")"), q); > > -// > > -// q = mfqp.parse(_T("\"foo bar\"~4")); > > -// assertEquals(tc, _T("b:\"foo bar\"~4 t:\"foo bar\"~4"), q); > > -// > > -// // make sure that terms which have a field are not touched: > > -// q = mfqp.parse(_T("one f:two")); > > -// assertEquals(tc, _T("(b:one t:one) f:two"), q); > > -// > > -// // AND mode: > > -// mfqp.setDefaultOperator(QueryParser::AND_OPERATOR); > > -// q = mfqp.parse(_T("one two")); > > -// assertEquals(tc, _T("+(b:one t:one) +(b:two t:two)"), q); > > -// q = mfqp.parse(_T("\"aa bb cc\" \"dd ee\"")); > > -// assertEquals(tc, _T("+(b:\"aa bb cc\" t:\"aa bb cc\") +(b: > > \"dd ee\" t:\"dd ee\")"), q); > > -// > > -// _CLDELETE(a); > > -//} > > -// > > -//CuSuite *testMultiFieldQueryParser(void) > > -//{ > > -// CuSuite *suite = CuSuiteNew(_T("CLucene Multi-Field > QP Test")); > > -// > > -// SUITE_ADD_TEST(suite, tesStopwordsParsing); > > -// SUITE_ADD_TEST(suite, testMFQPSimple); > > -// > > -// return suite; > > -//} > > \ No newline at end of file > > +class MQPTestFilter: public TokenFilter { > > +public: > > + > > + bool inPhrase; > > + int32_t savedStart, savedEnd; > > + > > + /** > > + * Filter which discards the token 'stop' and which expands the > > + * token 'phrase' into 'phrase1 phrase2' > > + */ > > + MQPTestFilter(TokenStream* in): > > + TokenFilter(in,true), > > + inPhrase(false), > > + savedStart(0), > > + savedEnd(0) > > + { > > + } > > + > > + CL_NS(analysis)::Token* next(CL_NS(analysis)::Token*& token) { > > + if (inPhrase) { > > + if (token == NULL) token=_CLNEW > CL_NS(analysis)::Token(); > > + inPhrase = false; > > + token->set( _T("phrase2"), savedStart, savedEnd); > > + return token; > > + }else{ > > + while( input->next(token) ){ > > + if ( _tcscmp(token->termBuffer(), > _T("phrase")) == > > 0 ) { > > + inPhrase = true; > > + savedStart = token->startOffset(); > > + savedEnd = token->endOffset(); > > + token->set( _T("phrase1"), savedStart, > savedEnd); > > + return token; > > + }else if ( _tcscmp(token->termBuffer(), > > _T("stop") ) !=0 ){ > > + return token; > > + } > > + } > > + } > > + _CLDELETE(token); > > + return NULL; > > + } > > +}; > > + > > +class MQPTestAnalyzer: public Analyzer { > > +public: > > + MQPTestAnalyzer() { > > + } > > + > > + /** Filters LowerCaseTokenizer with StopFilter. */ > > + TokenStream* tokenStream(const TCHAR* fieldName, Reader* > > reader) { > > + return _CLNEW MQPTestFilter(_CLNEW > > LowerCaseTokenizer(reader)); > > + } > > +}; > > + > > +void assertEquals(CuTest *tc,const TCHAR* result, Query* q) { > > + if ( q == NULL ) > > + return; > > + > > + const TCHAR* s = q->toString(); > > + int ret = _tcscmp(s,result); > > + _CLDELETE(q); > > + if ( ret != 0 ) { > > + TCHAR buf[HUGE_STRING_LEN]; > > + _sntprintf(buf, HUGE_STRING_LEN, _T("FAILED Query > yielded / > > %s/, expecting /%s/\n"), s, result); > > + _CLDELETE_LCARRAY(s); > > + CuFail(tc, buf); > > + } > > + _CLDELETE_LCARRAY(s); > > +} > > + > > +// verify parsing of query using a stopping analyzer > > +void assertStopQueryEquals(CuTest *tc, const TCHAR* qtxt, const > > TCHAR* expectedRes) { > > + const TCHAR* fields[] = {_T("b"), _T("t"), NULL }; > > + const uint8_t occur[] = {BooleanClause::SHOULD, > > BooleanClause::SHOULD, NULL}; > > + MQPTestAnalyzer *a = _CLNEW MQPTestAnalyzer(); > > + MultiFieldQueryParser mfqp(fields, a); > > + > > + Query *q = mfqp.parse(qtxt); > > + assertEquals(tc, expectedRes, q); > > + > > + q = MultiFieldQueryParser::parse(qtxt, reinterpret_cast<const > > TCHAR**>(&fields), > > + reinterpret_cast<const uint8_t*>(&occur), a); > > + assertEquals(tc, expectedRes, q); > > + _CLDELETE(a); > > +} > > + > > +/** test stop words arsing for both the non static form, > and for the > > +* corresponding static form (qtxt, fields[]). */ > > +void tesStopwordsParsing(CuTest *tc) { > > + assertStopQueryEquals(tc, _T("one"), _T("b:one t:one")); > > + assertStopQueryEquals(tc, _T("one stop"), _T("b:one t:one")); > > + assertStopQueryEquals(tc, _T("one (stop)"), _T("b:one t:one")); > > + assertStopQueryEquals(tc, _T("one ((stop))"), > _T("b:one t:one")); > > + assertStopQueryEquals(tc, _T("stop"), _T("")); > > + assertStopQueryEquals(tc, _T("(stop)"), _T("")); > > + assertStopQueryEquals(tc, _T("((stop))"), _T("")); > > +} > > + > > +void testMFQPSimple(CuTest *tc) { > > + const TCHAR* fields[] = {_T("b"), _T("t"), NULL}; > > + Analyzer* a = _CLNEW StandardAnalyzer(); > > + MultiFieldQueryParser mfqp(fields, a); > > + > > + Query *q = mfqp.parse(_T("one")); > > + assertEquals(tc, _T("b:one t:one"), q); > > + > > + q = mfqp.parse(_T("one two")); > > + assertEquals(tc, _T("(b:one t:one) (b:two t:two)"),q); > > + > > + q = mfqp.parse(_T("+one +two")); > > + assertEquals(tc, _T("+(b:one t:one) +(b:two t:two)"), q); > > + > > + q = mfqp.parse(_T("+one -two -three")); > > + assertEquals(tc, _T("+(b:one t:one) -(b:two t:two) -(b:three > > t:three)"), q); > > + > > + q = mfqp.parse(_T("one^2 two")); > > + assertEquals(tc, _T("((b:one t:one)^2.0) (b:two t:two)"), q); > > + > > + q = mfqp.parse(_T("one~ two")); > > + assertEquals(tc, _T("(b:one~0.5 t:one~0.5) (b:two t:two)"), q); > > + > > + q = mfqp.parse(_T("one~0.8 two^2")); > > + assertEquals(tc, _T("(b:one~0.8 t:one~0.8) ((b:two > > t:two)^2.0)"), q); > > + > > + q = mfqp.parse(_T("one* two*")); > > + assertEquals(tc, _T("(b:one* t:one*) (b:two* t:two*)"), q); > > + > > + q = mfqp.parse(_T("[a TO c] two")); > > + assertEquals(tc, _T("(b:[a TO c] t:[a TO c]) (b:two > t:two)"), q); > > + > > + q = mfqp.parse(_T("w?ldcard")); > > + assertEquals(tc, _T("b:w?ldcard t:w?ldcard"), q); > > + > > + q = mfqp.parse(_T("\"foo bar\"")); > > + assertEquals(tc, _T("b:\"foo bar\" t:\"foo bar\""), q); > > + > > + q = mfqp.parse(_T("\"aa bb cc\" \"dd ee\"")); > > + assertEquals(tc, _T("(b:\"aa bb cc\" t:\"aa bb cc\") > (b:\"dd ee > > \" t:\"dd ee\")"), q); > > + > > + q = mfqp.parse(_T("\"foo bar\"~4")); > > + assertEquals(tc, _T("b:\"foo bar\"~4 t:\"foo bar\"~4"), q); > > + > > + // make sure that terms which have a field are not touched: > > + q = mfqp.parse(_T("one f:two")); > > + assertEquals(tc, _T("(b:one t:one) f:two"), q); > > + > > + // AND mode: > > + mfqp.setDefaultOperator(QueryParser::AND_OPERATOR); > > + q = mfqp.parse(_T("one two")); > > + assertEquals(tc, _T("+(b:one t:one) +(b:two t:two)"), q); > > + q = mfqp.parse(_T("\"aa bb cc\" \"dd ee\"")); > > + assertEquals(tc, _T("+(b:\"aa bb cc\" t:\"aa bb cc\") > +(b:\"dd > > ee\" t:\"dd ee\")"), q); > > + > > + _CLDELETE(a); > > +} > > + > > +CuSuite *testMultiFieldQueryParser(void) > > +{ > > + CuSuite *suite = CuSuiteNew(_T("CLucene Multi-Field QP Test")); > > + > > + SUITE_ADD_TEST(suite, tesStopwordsParsing); > > + SUITE_ADD_TEST(suite, testMFQPSimple); > > + > > + return suite; > > +} > > \ No newline at end of file > > > > Modified: branches/lucene2_3_2/src/test/tests.cpp > > =================================================================== > > --- branches/lucene2_3_2/src/test/tests.cpp 2009-05-03 21:01:38 > > UTC (rev 3005) > > +++ branches/lucene2_3_2/src/test/tests.cpp 2009-05-04 14:46:40 > > UTC (rev 3006) > > @@ -16,7 +16,7 @@ > > {"highfreq", testhighfreq}, > > {"priorityqueue", testpriorityqueue}, > > {"queryparser", testQueryParser}, > > - //{"mfqueryparser", testMultiFieldQueryParser}, > > + {"mfqueryparser", testMultiFieldQueryParser}, > > {"search", testsearch}, > > {"queries", testqueries}, > > {"termvector",testtermvector}, > > > > > > This was sent by the SourceForge.net collaborative development > > platform, the world's largest Open Source development site. > > > > --- > > --- > > --- > > > --------------------------------------------------------------------- > > Register Now & Save for Velocity, the Web Performance & Operations > > Conference from O'Reilly Media. Velocity features a full day of > > expert-led, hands-on workshops and two days of sessions > from industry > > leaders in dedicated Performance & Operations tracks. Use code > > vel09scf > > and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf > > _______________________________________________ > > Clucene-cvs mailing list > > Clu...@li... > > https://lists.sourceforge.net/lists/listinfo/clucene-cvs > > iorityqueue", testpriorityqueue}, > > {"queryparser", testQueryParser}, > > - //{"mfqueryparser", testMultiFieldQueryParser}, > > + {"mfqueryparser", testMultiFieldQueryParser}, > > {"search", testsearch}, > > {"queries", testqueries}, > > {"termvector",testtermvector}, > > > > > > This was sent by the SourceForge.net collaborative development > > platform, the world's largest Open Source development site. > > > > --- > > --- > > --- > > > --------------------------------------------------------------------- > > Register Now & Save for Velocity, the Web Performance & Operations > > Conference from O'Reilly Media. Velocity features a full day of > > expert-led, hands-on workshops and two days of sessions > from industry > > leaders in dedicated Performance & Operations tracks. Use code > > vel09scf > > and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf > > _______________________________________________ > > Clucene-cvs mailing list > > Clu...@li... > > https://lists.sourceforge.net/lists/listinfo/clucene-cvs > > istinfo/clucene-cvs > > -------------------------------------------------------------- > ---------------- > The NEW KODAK i700 Series Scanners deliver under ANY > circumstances! Your > production scanning environment may not be a perfect world - > but thanks to > Kodak, there's a perfect scanner to get the job done! With > the NEW KODAK i700 > Series Scanner you'll get full speed at 300 dpi even with all image > processing features enabled. http://p.sf.net/sfu/kodak-com > _______________________________________________ > Clucene-cvs mailing list > Clu...@li... > https://lists.sourceforge.net/lists/listinfo/clucene-cvs > > |