]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.indexing/src/org/simantics/db/indexing/Queries.java
Index tokenized lowercase versions of name and types for UI searches
[simantics/platform.git] / bundles / org.simantics.db.indexing / src / org / simantics / db / indexing / Queries.java
index 1ea64d0f2bf159418c942d4b3c3cdd01fc130924..21b32fa1ecd14d1ae0a5238095365d4dbd56f6ff 100644 (file)
  *******************************************************************************/
 package org.simantics.db.indexing;
 
+import java.io.IOException;
 import java.io.Reader;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Pattern;
 
 import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.TokenFilter;
+import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
 import org.apache.lucene.analysis.core.KeywordAnalyzer;
 import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
 import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
+import org.apache.lucene.analysis.pattern.PatternReplaceFilter;
+import org.apache.lucene.analysis.pattern.PatternTokenizer;
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
 import org.apache.lucene.analysis.util.CharTokenizer;
 import org.apache.lucene.queryparser.classic.ParseException;
 import org.apache.lucene.queryparser.classic.QueryParser;
@@ -30,6 +37,7 @@ import org.apache.lucene.search.Query;
 import org.apache.lucene.util.AttributeFactory;
 import org.apache.lucene.util.Version;
 import org.simantics.databoard.util.ObjectUtils;
+import org.simantics.db.layer0.genericrelation.Dependencies;
 import org.simantics.utils.datastructures.Pair;
 
 public class Queries {
@@ -90,6 +98,39 @@ public class Queries {
         }
     }
 
+    final static class LowercaseFilter extends TokenFilter {
+        private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
+
+        public LowercaseFilter(TokenStream in) {
+            super(in);
+        }
+
+        @Override
+        public boolean incrementToken() throws IOException {
+            if (!input.incrementToken()) return false;
+            String lowercase = termAtt.toString().toLowerCase();
+            termAtt.setEmpty().append(lowercase);
+            return true;
+        }
+    }
+
+    static final class TypeStringAnalyzer extends Analyzer {
+        private boolean lowercase;
+
+        public TypeStringAnalyzer(Boolean lowercase) {
+            this.lowercase = lowercase;
+        }
+        
+        @Override
+        protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
+                       Tokenizer tokenizer = new PatternTokenizer(reader, Pattern.compile("(([^\\\\ ]|\\\\\\\\|\\\\ )+)( *)"), 1);
+                       TokenFilter filter = new PatternReplaceFilter(tokenizer, Pattern.compile("(\\\\(\\\\| ))"), "$2", true);
+                       
+                       return new TokenStreamComponents(tokenizer, lowercase ? new LowercaseFilter(filter) : filter);
+               }
+               
+       }
+
     private static AtomicReference<Pair<Query, String>> queryCache = new AtomicReference<>();
 
     final static PerFieldAnalyzerWrapper analyzer = createAnalyzer();
@@ -101,6 +142,10 @@ public class Queries {
        analyzerPerField.put("Parent", new KeywordAnalyzer());
        analyzerPerField.put("Resource", new KeywordAnalyzer());
        analyzerPerField.put("GUID", new KeywordAnalyzer());
+       analyzerPerField.put("Name", new KeywordAnalyzer());
+       analyzerPerField.put("Types", new TypeStringAnalyzer(false));
+       analyzerPerField.put(Dependencies.FIELD_NAME_SEARCH, new LowerCaseWhitespaceAnalyzer(Version.LUCENE_4_9));
+       analyzerPerField.put(Dependencies.FIELD_TYPES_SEARCH, new TypeStringAnalyzer(true));
        
         PerFieldAnalyzerWrapper analyzer = new PerFieldAnalyzerWrapper(new LowerCaseWhitespaceAnalyzer(Version.LUCENE_4_9), analyzerPerField);
         return analyzer;
@@ -118,6 +163,7 @@ public class Queries {
 
         //System.err.println("parse " + search + " (cached=" + (cachedQuery != null ? cachedQuery.second : "null") + ")" );
         CustomQueryParser parser = new CustomQueryParser(Version.LUCENE_4_9, "Name", getAnalyzer(), schema);
+        parser.setLowercaseExpandedTerms(false);
         Query query = parser.parse(search);
 
         queryCache.set(Pair.make(query, search));