The real acknowledged problem here is that we are trying to mimic an older system.
I've found searching on all fields (generating queries for lucene's query parser) to be quite slow (for one of our objects we have ~170 fields). Using the same name like:
Code:
@Fields( {
@Field(index = Index.TOKENIZED),
@Field(name = "ALL", index = Index.TOKENIZED)
} )
Doesn't work for subobjects. To get around this I did this:
Throw a class bridge on the object i want indexed:
Code:
@ClassBridge(name = "ALL", index = Index.TOKENIZED, store = Store.YES, impl = AllBridge.class)
Make an AllBridge class (which uses the same concept as (
http://community.jboss.org/wiki/Hiberna ... Extraction):
Code:
public class AllBridge<T extends Domain> implements FieldBridge, StringBridge {
@Override
public void set(String name, Object value, Document document, LuceneOptions luceneoptions) {
if (value != null) {
Domain domain = (Domain) value;
LazyAllField lazyAllField = new LazyAllField(name, document, luceneoptions);
// document.add(new Field(name, "foo bar biz bat", luceneoptions.getStore(), luceneoptions.getIndex(), luceneoptions
// .getTermVector()));
document.add(lazyAllField);
}
}
@Override
public String objectToString(Object incomingQuery) {
return (String) incomingQuery;
}
}
Finally the LazyAllField:
Code:
public class LazyAllField extends AbstractField implements Fieldable {
public static TextExtractor extrator = new TextExtractor();
private String content;
private final Document document;
public LazyAllField(String name, Document document, LuceneOptions luceneOptions) {
super(name, luceneOptions.getStore(), luceneOptions.getIndex(), Field.TermVector.NO);
this.document = document;
// fundamental set: this instructs Lucene not to call the stringValue on field creation, but only when needed
lazy = true;
}
public byte[] binaryValue() {
return null;
}
public Reader readerValue() {
return null;
}
public TokenStream tokenStreamValue() {
return null;
}
public String stringValue() {
if (content == null) {
content = "";
StringBuffer buffer = new StringBuffer();
for (Fieldable fieldable : document.getFields()) {
if (fieldable != this) {
buffer.append(fieldable.stringValue());
buffer.append(" ");
}
}
content = buffer.toString();
}
return content;
}
}
This isn't rigorously tested by me (so use at your own risk), but it works. It does take a massive amount of heap currently.