]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5237 - Updated RuleService#search
authorStephane Gamard <stephane.gamard@searchbox.com>
Wed, 30 Apr 2014 14:34:51 +0000 (16:34 +0200)
committerStephane Gamard <stephane.gamard@searchbox.com>
Wed, 30 Apr 2014 14:37:03 +0000 (16:37 +0200)
sonar-server/src/main/java/org/sonar/server/rule2/RuleIndex.java
sonar-server/src/main/java/org/sonar/server/search/BaseIndex.java
sonar-server/src/main/java/org/sonar/server/search/Hit.java
sonar-server/src/main/java/org/sonar/server/search/Results.java

index 4a138c4a3715feb8d26ee1814a3da4ab8812938c..00892f775e42c9b45c31148442618139296b9dd5 100644 (file)
  */
 package org.sonar.server.rule2;
 
-import org.sonar.server.rule2.RuleNormalizer.RuleField;
-
-import org.elasticsearch.action.search.SearchResponse;
 import com.google.common.collect.ImmutableSet;
+import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.index.query.MultiMatchQueryBuilder;
+import org.elasticsearch.index.query.BoolFilterBuilder;
+import org.elasticsearch.index.query.FilterBuilders;
 import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.SearchHit;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.rule.RuleKey;
@@ -35,7 +35,9 @@ import org.sonar.core.profiling.Profiling;
 import org.sonar.core.rule.RuleConstants;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.server.es.ESNode;
+import org.sonar.server.rule2.RuleNormalizer.RuleField;
 import org.sonar.server.search.BaseIndex;
+import org.sonar.server.search.Hit;
 import org.sonar.server.search.QueryOptions;
 import org.sonar.server.search.Results;
 
@@ -139,20 +141,43 @@ public class RuleIndex extends BaseIndex<RuleKey, RuleDto> {
 
   public Results search(RuleQuery query, QueryOptions options) {
 
-//    QueryBuilder qb;
-//    if(query.getQueryText() != null && !query.getQueryText().isEmpty()){
-//      qb = QueryBuilders.multiMatchQuery("test", "toto");
-//    } else {
-//      qb = QueryBuilders.matchAllQuery();
-//    }
-//
-//    SearchResponse esResult = getClient()
-//      .prepareSearch(this.getIndexName())
-//      .setQuery(qb)
-//      .get();
-//
-      Results results = new Results();
+    // Build main query (search based)
+    QueryBuilder qb;
+    if (query.getQueryText() != null && !query.getQueryText().isEmpty()) {
+      qb = QueryBuilders.multiMatchQuery(query.getQueryText(),
+        RuleField.NAME.key(),
+        RuleField.DESCRIPTION.key(),
+        RuleField.KEY.key(),
+        RuleField.LANGUAGE.key(),
+        RuleField.TAGS.key());
+    } else {
+      qb = QueryBuilders.matchAllQuery();
+    }
+
+    // Build main filter (match based)
+    BoolFilterBuilder fb = FilterBuilders.boolFilter();
+
+    this.addTermFilter(RuleField.LANGUAGE.key(), query.getLanguages(), fb);
+    this.addTermFilter(RuleField.REPOSITORY.key(), query.getRepositories(), fb);
+    this.addTermFilter(RuleField.SEVERITY.key(), query.getSeverities(), fb);
+    this.addTermFilter(RuleField.KEY.key(), query.getKey(), fb);
+
+    //Create ES query Object;
+    SearchResponse esResult = getClient()
+      .prepareSearch(this.getIndexName())
+      .setQuery(QueryBuilders.filteredQuery(qb, fb))
+      .addFields(options.getFieldsToReturn().toArray(new String[options.getFieldsToReturn().size()]))
+      .get();
+
+    Results results = new Results()
+      .setTotal((int) esResult.getHits().totalHits())
+      .setTime(esResult.getTookInMillis());
+
+    for (SearchHit hit : esResult.getHits().getHits()) {
+      results.getHits().add(
+        Hit.fromMap(hit.score(), hit.sourceAsMap()));
+    }
+
     return results;
   }
-
 }
index f7703c3894eff3f2ae9255fa7c9e81ae2ddc7bf1..986624d698287a1e6bf519d027a52e20435fcb0e 100644 (file)
@@ -29,6 +29,8 @@ import org.elasticsearch.action.update.UpdateRequest;
 import org.elasticsearch.action.update.UpdateResponse;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.index.query.BoolFilterBuilder;
+import org.elasticsearch.index.query.FilterBuilders;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.core.cluster.WorkQueue;
@@ -40,6 +42,7 @@ import org.sonar.server.es.ESNode;
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.Collection;
 
 public abstract class BaseIndex<K extends Serializable, E extends Dto<K>> implements Index<K> {
 
@@ -55,10 +58,10 @@ public abstract class BaseIndex<K extends Serializable, E extends Dto<K>> implem
   private final Profiling profiling;
   private Client client;
   private final ESNode node;
-  protected BaseNormalizer<E,K> normalizer;
+  protected BaseNormalizer<E, K> normalizer;
 
-  public BaseIndex(BaseNormalizer<E,K> normalizer, WorkQueue workQueue,
-                Profiling profiling, ESNode node) {
+  public BaseIndex(BaseNormalizer<E, K> normalizer, WorkQueue workQueue,
+    Profiling profiling, ESNode node) {
     this.normalizer = normalizer;
     this.profiling = profiling;
     this.node = node;
@@ -216,4 +219,26 @@ public abstract class BaseIndex<K extends Serializable, E extends Dto<K>> implem
     // TODO need to read that in the admin index;
     return 0l;
   }
+
+  /* ES QueryHelper Methods */
+
+  protected BoolFilterBuilder addTermFilter(String field, Collection<String> values, BoolFilterBuilder filter) {
+    if (values != null && !values.isEmpty()) {
+      BoolFilterBuilder valueFilter = FilterBuilders.boolFilter()
+        .cache(true)
+        .cacheKey(field + "_vs");
+      for (String value : values) {
+        valueFilter.should(FilterBuilders.termFilter(field, value));
+      }
+      filter.must(valueFilter);
+    }
+    return filter;
+  }
+
+  protected BoolFilterBuilder addTermFilter(String field, String value, BoolFilterBuilder filter) {
+    if (value != null && !value.isEmpty()) {
+      filter.must(FilterBuilders.termFilter(field, value));
+    }
+    return filter;
+  }
 }
index ea373a4ec09e7fd6c9a9c2e5c4e1e4b775e14737..32991d77c0435c805ff0496502727841aecb4a41 100644 (file)
@@ -28,12 +28,18 @@ public class Hit implements Comparable<Hit> {
   private Map<String, Object> fields;
 
   private Integer rank;
+  private Float score;
 
   public Hit(Integer rank) {
     this.fields = new HashMap<String, Object>();
     this.rank = rank;
   }
 
+  public Hit(Float score){
+    this.fields = new HashMap<String, Object>();
+    this.score = score;
+  }
+
   public Map<String, Object> getFields() {
     return this.fields;
   }
@@ -53,9 +59,17 @@ public class Hit implements Comparable<Hit> {
     return this.rank;
   }
 
+  public Float getScore() {
+    return this.score;
+  }
+
   @Override
   public int compareTo(Hit hit) {
-    return this.getRank().compareTo(hit.getRank());
+    if (this.getRank() != null) {
+      return this.getRank().compareTo(hit.getRank());
+    } else {
+      return this.getScore().compareTo(hit.getScore());
+    }
   }
 
   public static Hit fromMap(Integer rank, Map<String, Object> fieldMap) {
@@ -63,4 +77,10 @@ public class Hit implements Comparable<Hit> {
     hit.fields = fieldMap;
     return hit;
   }
+
+  public static Hit fromMap(float score, Map<String, Object> fieldMap) {
+    Hit hit = new Hit(score);
+    hit.fields = fieldMap;
+    return hit;
+  }
 }
index 3504fb2ad76314783f8efb23e6945cc2019ae48f..48c6fd246cda90e63fbfcfa6cc4136d35dfaf727 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.search;
 
+import java.util.ArrayList;
 import java.util.Collection;
 
 public class Results {
@@ -29,6 +30,12 @@ public class Results {
 
   private int offset;
 
+  private long time;
+
+  public Results() {
+    this.hits = new ArrayList<Hit>();
+  }
+
   public Collection<Hit> getHits() {
     return hits;
   }
@@ -40,4 +47,23 @@ public class Results {
   public int getOffset() {
     return offset;
   }
+
+  public Results setTotal(int total) {
+    this.total = total;
+    return this;
+  }
+
+  public Results setOffset(int offset) {
+    this.offset = offset;
+    return this;
+  }
+
+  public long getTime() {
+    return time;
+  }
+
+  public Results setTime(long time) {
+    this.time = time;
+    return this;
+  }
 }