0) {
var arr = java.lang.reflect.Array.newInstance(pkg.SortField, this.sortFields.size());
var sort = pkg.Sort(this.sortFields.toArray(arr));
if (filter) {
hits = searcher.search(query, filter, sort);
} else {
hits = searcher.search(query, sort);
}
} else if (filter) {
hits = searcher.search(query, filter);
} else {
hits = searcher.search(query);
}
this.hits = new helma.Search.HitCollection(hits);
return this.hits.length();
};
/**
* Sets a field as result sorting field. This method can be called
* with a different number of arguments:
* sortBy(fieldName)
* sortBy(fieldName, type)
* sortBy(fieldName, reverse)
* sortBy(fieldName, type, reverse)
* @param {String} fieldName The name of the field in the index by which
* the search result should be ordered.
* @param {String} type The type of the field defined by argument fieldName.
* Valid arguments are "string", "float", "int", "score", "doc", "auto", "custom".
* Default is "auto". See http://lucene.apache.org/java/docs/api/org/apache/lucene/search/SortField.html
* for an explanation.
*/
helma.Search.Searcher.prototype.sortBy = function(fieldName /** type, reverse */) {
var pkg = Packages.org.apache.lucene.search;
if (!this.sortFields)
this.sortFields = new java.util.Vector();
var f = fieldName;
var t = pkg.SortField.AUTO;
var r = false;
if (arguments.length == 3) {
t = pkg.SortField[arguments[1].toUpperCase()];
r = arguments[2];
} else if (arguments.length == 2) {
if (arguments[1].constructor == Boolean) {
r = arguments[1];
} else {
t = pkg.SortField[arguments[1].toUpperCase()];
}
}
this.sortFields.add(new pkg.SortField(f, t, r));
return;
};
/**
* Closes the wrapped IndexSearcher instance.
*/
helma.Search.Searcher.prototype.close = function() {
var s = this.getSearcher();
if (s != null) {
s.close();
}
return;
};
/**
* Creates a new instance of helma.Search.HitCollection
* @class This class provides Helma-like methods for accessing
* a collection of search hits.
* @param {org.lucene.search.Hits} hits The hit collection returned
* by lucene.
* @constructor
*/
helma.Search.HitCollection = function(hits) {
/**
* Silently converts the hit at the given index position into
* an instance of helma.Search.Document.
* @param {Number} idx The index position of the hit
* @returns The document object at the given index position
* @type helma.Search.Document
*/
this.get = function(idx) {
var doc = new helma.Search.Document(hits.doc(idx));
doc.id = hits.id(idx);
doc.score = hits.score(idx);
doc.rank = idx +1;
return doc;
};
/**
* Returns the number of hits in this collection.
* @returns The number of hits.
* @type Number
*/
this.size = function() {
return (hits != null) ? hits.length() : 0;
};
/**
* Returns the number of hits in this collection.
* This method is deprecated, use {@link #size} instead.
* @returns The number of hits.
* @type Number
* @deprecated
* @see #size
*/
this.length = function() {
return this.size();
};
/**
* Executes a provided function once per hit.
* @param {Function} fun Function to execute for each element
* @param {Object} context Object to use as "this" when executing callback.
* @see https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/ForEach
*/
this.forEach = function(func, context) {
if (typeof func != "function") {
throw new TypeError();
}
var len = this.size();
for (var i = 0; i < len; i += 1) {
var hit = this.get(i);
if (hit) {
func.call(context, hit, i, hits);
}
}
return;
};
return this;
};
/** @ignore */
helma.Search.HitCollection.prototype.toString = function() {
return "[HitCollection]";
};
/***********************************************
***** Q U E R Y C O N S T R U C T O R S *****
***********************************************/
/**
* Creates a new instance of helma.Search.Query
* @class Base class for the various query constructors. Don't
* call this directly, as it provides just basic methods used
* in all of its extends.
* @constructor
*/
helma.Search.Query = function() {
/**
* The wrapped query instance
* @type org.apache.lucene.search.Query
* @private
*/
this.query = null;
return this;
};
/**
* Returns the wrapped Lucene Query object.
* @returns The wrapped query object
* @type org.apache.lucene.search.Query
*/
helma.Search.Query.prototype.getQuery = function() {
return this.query;
};
/** @ignore */
helma.Search.Query.prototype.toString = function(field) {
return "[" + this.getQuery().toString(field) + "]";
};
/**
* Returns the boost factor of this query.
* @type Number
*/
helma.Search.Query.prototype.getBoost = function() {
return this.getQuery().getBoost();
};
/**
* Sets the boost factor of this query clause to
* the given number. Documents matching this query
* will have their score multiplied with the given
* factor
* @param {Number} fact The factor to multiply the score
* of matching documents with.
*/
helma.Search.Query.prototype.setBoost = function(fact) {
this.getQuery().setBoost(fact);
return;
};
/**
* Creates a new instance of helma.Search.TermQuery
* @class This class represents a simple Term Query.
* @param {String} field The name of the field
* @param {String} str The value of the field
* @constructor
* @extends helma.Search.Query
*/
helma.Search.TermQuery = function(field, str) {
var t = new Packages.org.apache.lucene.index.Term(field, str);
/**
* Contains the wrapped TermQuery instance
* @type org.apache.lucene.search.TermQuery
*/
this.query = new Packages.org.apache.lucene.search.TermQuery(t);
return this;
};
helma.Search.TermQuery.prototype = new helma.Search.Query;
/**
* Creates a new instance of helma.Search.BooleanQuery
* @class This class represents a Boolean Query, providing
* various methods for combining other Query instances using boolean operators.
* @param String name of the field
* @param String query string
* @returns Object BooleanQuery object
* @constructor
* @extends helma.Search.Query
*/
helma.Search.BooleanQuery = function(field, str, clause, analyzer) {
/**
* Contains the wrapped BooleanQuery instance
* @type org.apache.lucene.search.BooleanQuery
*/
this.query = new Packages.org.apache.lucene.search.BooleanQuery();
/**
* Main constructor body
*/
if (field && str) {
this.addTerm.apply(this, arguments);
}
return this;
};
helma.Search.BooleanQuery.prototype = new helma.Search.Query;
/**
* Adds a term to the wrapped query object. This method can be called
* with two, three or four arguments, eg.:
* addTerm("fieldname", "querystring")
* addTerm("fieldname", "querystring", "and")
* addTerm("fieldname", "querystring", helma.Search.getAnalyzer("de"))
* addTerm("fieldname", "querystring", "not", helma.Search.getAnalyzer("simple"))
* @param {String|Array} field Either a String or an Array containing Strings
* that determine the index field(s) to match
* @param {String} str Query string to match
* @param {String} clause Boolean clause ("or", "not" or "and", default is "and")
* @param {org.apache.lucene.analysis.Analyzer} analyzer An analyzer to use
*/
helma.Search.BooleanQuery.prototype.addTerm = function(field, str, clause, analyzer) {
var pkg = Packages.org.apache.lucene;
if (arguments.length == 3 && arguments[2] instanceof pkg.analysis.Analyzer) {
analyzer = arguments[2];
clause = "or";
}
if (!analyzer) {
analyzer = helma.Search.getAnalyzer();
}
var fields = (field instanceof Array) ? field : [field];
var parser = new pkg.queryParser.MultiFieldQueryParser(fields, analyzer);
this.addQuery(parser.parse(str), clause);
return;
};
/**
* Adds an additional query clause to this query.
* @param {helma.Search.Query} q The query to add
* @param {String} clause Boolean clause ("or", "not", or "and", default is "and")
*/
helma.Search.BooleanQuery.prototype.addQuery = function(q, clause) {
var pkg = Packages.org.apache.lucene;
var booleanClause;
if (q instanceof helma.Search.Query) {
q = q.getQuery();
}
switch (clause) {
case "and":
booleanClause = pkg.search.BooleanClause.Occur.MUST;
break;
case "not":
booleanClause = pkg.search.BooleanClause.Occur.MUST_NOT;
break;
default:
booleanClause = pkg.search.BooleanClause.Occur.SHOULD;
break;
}
this.getQuery().add(q, booleanClause);
return;
};
/**
* Constructs a new helma.Search.PhraseQuery instance that wraps
* a Lucene Phrase Query object.
* @class Instances of this class represent a phrase query.
* @param {String} field The name of the field
* @param {String} str The phrase query string
* @returns A newly created PhraseQuery instance
* @constructor
* @extends helma.Search.Query
*/
helma.Search.PhraseQuery = function(field, str) {
/**
* Contains the wrapped PhraseQuery instance
* @type org.apache.lucene.search.PhraseQuery
*/
this.query = new Packages.org.apache.lucene.search.PhraseQuery();
/**
* add a term to the end of the phrase query
*/
this.addTerm = function(field, str) {
var t = new Packages.org.apache.lucene.index.Term(field, str);
this.query.add(t);
return;
};
if (field && str)
this.addTerm(field, str);
delete this.base;
return this;
};
helma.Search.PhraseQuery.prototype = new helma.Search.Query;
/**
* Constructs a new helma.Search.RangeQuery instance.
* @class Instances of this class represent a range
* query, wrapping a Lucene RangeQuery instance.
* @param {String} field The name of the field
* @param {String} from The minimum value to match (can be null)
* @param {String} to The maximum value to match (can be null)
* @param {Boolean} inclusive If true the given min/max values are included
* @returns A newly created RangeQuery instance
* @constructor
* @extends helma.Search.Query
*/
helma.Search.RangeQuery = function(field, from, to, inclusive) {
if (!field)
throw "Missing field name in RangeQuery()";
if (arguments.length < 4)
inclusive = true;
var t1 = from ? new Packages.org.apache.lucene.index.Term(field, from) : null;
var t2 = to ? new Packages.org.apache.lucene.index.Term(field, to) : null;
/**
* Contains the wrapped RangeQuery instance
* @type org.apache.lucene.search.RangeQuery
*/
this.query = new Packages.org.apache.lucene.search.RangeQuery(t1, t2, inclusive);
return this;
};
helma.Search.RangeQuery.prototype = new helma.Search.Query;
/**
* Constructs a new helma.Search.FuzzyQuery instance.
* @class Instances of this class represent a fuzzy query
* @param {String} field The name of the field
* @param {String} str The query string to match
* @returns A newly created FuzzyQuery instance
* @constructor
* @extends helma.Search.Query
*/
helma.Search.FuzzyQuery = function(field, str) {
var t = new Packages.org.apache.lucene.index.Term(field, str);
/**
* Contains the wrapped FuzzyQuery instance
* @type org.apache.lucene.search.FuzzyQuery
*/
this.query = new Packages.org.apache.lucene.search.FuzzyQuery(t);
return this;
};
helma.Search.FuzzyQuery.prototype = new helma.Search.Query;
/**
* Constructs a new helma.Search.PrefixQuery instance.
* @class Instances of this class represent a prefix query
* @param {String} field The name of the field
* @param {String} str The query string to match
* @returns A newly created PrefixQuery instance
* @constructor
* @extends helma.Search.Query
*/
helma.Search.PrefixQuery = function(field, str) {
var t = new Packages.org.apache.lucene.index.Term(field, str);
/**
* Contains the wrapped PrefixQuery instance
* @type org.apache.lucene.search.PrefixQuery
*/
this.query = new Packages.org.apache.lucene.search.PrefixQuery(t);
return this;
};
helma.Search.PrefixQuery.prototype = new helma.Search.Query;
/**
* Constructs a new helma.Search.WildcardQuery instance.
* @class Instances of this class represent a wildcard query.
* @param {String} field The name of the field
* @param {String} str The query string to match
* @returns A newly created WildcardQuery instance
* @constructor
* @extends helma.Search.Query
*/
helma.Search.WildcardQuery = function(field, str) {
var t = new Packages.org.apache.lucene.index.Term(field, str);
/**
* Contains the wrapped WildcardQuery instance
* @type org.apache.lucene.search.WildcardQuery
*/
this.query = new Packages.org.apache.lucene.search.WildcardQuery(t);
return this;
};
helma.Search.WildcardQuery.prototype = new helma.Search.Query;
/***************************
***** D O C U M E N T *****
***************************/
/**
* Creates a new instance of helma.Search.Document.
* @class Instances of this class represent a single
* index document. This class provides various methods for
* adding content to such documents.
* @param {org.apache.lucene.document.Document} document Optional Lucene Document object
* that should be wrapped by this Document instance.
* @constructor
*/
helma.Search.Document = function(document) {
if (!document) {
document = new Packages.org.apache.lucene.document.Document();
}
/**
* Returns the wrapped Lucene Document object
* @returns The wrapped Document object
* @type org.apache.lucene.document.Document
*/
this.getDocument = function() {
return document;
};
return this;
};
/**
* Adds a field to this document.
* @param {String|helma.Search.Document.Field} name The name of the field, or
* an instance of {@link helma.Search.Document.Field}, in which case the other
* arguments are ignored.
* @param {String} value The value of the field
* @param {Object} options Optional object containing the following properties
* (each of them is optional too):
*
* store
(String) Defines whether and how the value is stored
* in the field. Accepted values are "no", "yes" and "compress" (defaults to "yes")
* index
(String) Defines whether and how the value is indexed
* in the field. Accepted values are "no", "tokenized", "unTokenized" and
* "noNorms" (defaults to "tokenized")
* termVector
(String) Defines if and how the fiels should have
* term vectors. Accepted values are "no", "yes", "withOffsets", "withPositions"
* and "withPositionsAndOffsets" (defaults to "no")
*
*/
helma.Search.Document.prototype.addField = function(name, value, options) {
if (!name) {
throw "helma.Search: missing arguments to Document.addField";
} else if (arguments.length == 1) {
if (arguments[0] instanceof Packages.org.apache.lucene.document.Field) {
this.getDocument().add(arguments[0]);
} else if (arguments[0] instanceof helma.Search.Document.Field) {
this.getDocument().add(arguments[0].getField());
}
return;
}
// for backwards compatibility only
if (options != null) {
if (typeof(options.store) === "boolean") {
options.store = (options.store === true) ? "yes" : "no";
}
if (typeof(options.index) === "boolean") {
if (options.index === true) {
options.index = (options.tokenize === true) ? "tokenized" : "unTokenized";
} else {
options.index = "no";
}
delete options.tokenize;
}
}
this.addField(new helma.Search.Document.Field(name, value, options));
return;
};
/**
* Returns a single document field.
* @param {String} name The name of the field in this document object.
* @returns The field with the given name
* @type helma.Search.Document.Field
*/
helma.Search.Document.prototype.getField = function(name) {
var f = this.getDocument().getField(name);
if (f != null) {
return new helma.Search.Document.Field(f);
}
return null;
};
/**
* Returns the fields of a document object. If a name is passed as argument,
* this method returns only the fields with the given name
* @param {String} name Optional name of the fields to return
* @returns An array containing all fields in this document object.
* @type Array
*/
helma.Search.Document.prototype.getFields = function(name) {
var fields;
if (name != null) {
fields = this.getDocument().getFields(name);
} else {
fields = this.getDocument().getFields().toArray();
}
var size = fields.length;
var result = new Array(size);
for (var i=0; i
* store
(String) Defines whether and how the value is stored
* in the field. Accepted values are "no", "yes" and "compress" (defaults to "yes")
* index
(String) Defines whether and how the value is indexed
* in the field. Accepted values are "no", "tokenized", "unTokenized" and
* "noNorms" (defaults to "tokenized")
* termVector
(String) Defines if and how the fiels should have
* term vectors. Accepted values are "no", "yes", "withOffsets", "withPositions"
* and "withPositionsAndOffsets" (defaults to "no")
*
*/
helma.Search.Document.Field = function(name, value, options) {
var field;
/**
* Contains the name of the field
* @type String
*/
this.name = undefined; // for documentation purposes only
this.__defineGetter__("name", function() {
return field.name();
});
/**
* Contains the string value of the field
* @type String
*/
this.value = undefined; // for documentation purposes only
this.__defineGetter__("value", function() {
return field.stringValue();
});
/**
* Contains the value of the field converted into a date object.
* @type String
*/
this.dateValue = undefined; // for documentation purposes only
this.__defineGetter__("dateValue", function() {
return Packages.org.apache.lucene.document.DateTools.stringToDate(this.value);
});
/**
* Returns the wrapped field instance
* @returns The wrapped field
* @type org.apache.lucene.document.Field
*/
this.getField = function() {
return field;
};
/**
* Main constructor body
*/
if (arguments.length == 1 && arguments[0] instanceof Packages.org.apache.lucene.document.Field) {
// calling the constructor with a single field argument is
// only used internally (eg. in Document.getFields())
field = arguments[0];
} else {
var pkg = Packages.org.apache.lucene.document.Field;
// default options
var store = pkg.Store.YES;
var index = pkg.Index.TOKENIZED;
var termVector = pkg.TermVector.NO;
var opt;
if (options != null) {
if (options.store != null) {
opt = options.store.toUpperCase();
if (opt == "YES" || opt == "NO" || opt == "COMPRESS") {
store = pkg.Store[opt];
} else {
app.logger.warn("helma.Search: unknown field storage option '" +
options.store + "'");
}
}
if (options.index != null) {
opt = options.index.toUpperCase();
if (opt == "TOKENIZED" || opt == "NO") {
index = pkg.Index[opt];
} else if (opt == "UNTOKENIZED") {
index = pkg.Index.UN_TOKENIZED;
} else if (opt == "NONORMS") {
index = pkg.Index.NO_NORMS;
} else {
app.logger.warn("helma.Search: unknown field indexing option '" +
options.index + "'");
}
}
if (options.termVector != null) {
opt = options.termVector.toUpperCase();
if (opt == "NO" || opt == "YES") {
termVector = pkg.TermVector[opt];
} else if (opt == "WITHOFFSETS") {
termVector = pkg.TermVector.WITH_OFFSETS;
} else if (opt == "WITHPOSITIONS") {
termVector = pkg.TermVector.WITH_POSITIONS;
} else if (opt == "WITHPOSITIONSANDOFFSETS") {
termVector = pkg.TermVector.WITH_POSITIONS_OFFSETS;
} else {
app.logger.warn("helma.Search: unknown field term vector option '" +
options.termVector + "'");
}
}
}
// construct the field instance and add it to this document
field = new Packages.org.apache.lucene.document.Field(
name, helma.Search.Document.Field.valueToString(value),
store, index, termVector);
}
return this;
};
/**
* Converts the value passed as argument to the appropriate string value. For
* null values this method returns an empty string.
* @param {Object} value The value to convert into a string
* @returns The value converted into a string
* @type String
*/
helma.Search.Document.Field.valueToString = function(value) {
var pkg = Packages.org.apache.lucene.document;
if (value != null) {
if (value.constructor === Date) {
return pkg.DateTools.timeToString(value.getTime(), pkg.DateTools.Resolution.MINUTE);
} else if (value.constructor !== String) {
return String(value);
}
return value;
}
return "";
};
/** @ignore */
helma.Search.Document.Field.prototype.toString = function() {
return "[Field '" + this.name + "' (" + this.getField().toString() + ")]";
};
/**
* Returns the boost factor of this field.
* @returns The boost factor of this field
* @type Number
*/
helma.Search.Document.Field.prototype.getBoost = function() {
return this.getField().getBoost();
};
/**
* Sets the boost factor of this field.
* @param {Number} boost The boost factor of this field
*/
helma.Search.Document.Field.prototype.setBoost = function(boost) {
this.getField().setBoost(boost);
app.logger.debug("boost is now: " + this.getField().getBoost());
return;
};
/**
* Returns true if this field is indexed
* @returns True if this field's value is indexed, false otherwise
* @type Boolean
*/
helma.Search.Document.Field.prototype.isIndexed = function() {
return this.getField().isIndexed();
};
/**
* Returns true if this field's value is stored in compressed form in the index
* @returns True if this field's value is compressed, false otherwise
* @type Boolean
*/
helma.Search.Document.Field.prototype.isCompressed = function() {
return this.getField().isCompressed();
};
/**
* Returns true if this field's value is stored in the index
* @returns True if this field's value is stored, false otherwise
* @type Boolean
*/
helma.Search.Document.Field.prototype.isStored = function() {
return this.getField().isStored();
};
/**
* Returns true if this field's value is tokenized
* @returns True if this field's value is tokenized, false otherwise
* @type Boolean
*/
helma.Search.Document.Field.prototype.isTokenized = function() {
return this.getField().isTokenized();
};
/**
* Returns true if this field's term vector is stored in the index
* @returns True if this field's term vector is stored, false otherwise
* @type Boolean
*/
helma.Search.Document.Field.prototype.isTermVectorStored = function() {
return this.getField().isTermVectorStored();
};
helma.lib = "Search";
helma.dontEnum(helma.lib);
for (var i in helma[helma.lib])
helma[helma.lib].dontEnum(i);
for (var i in helma[helma.lib].prototype)
helma[helma.lib].prototype.dontEnum(i);
delete helma.lib;