Explorar el Código

fix #1820 OR query problem

Shinsuke Sugaya hace 6 años
padre
commit
5a0f028da5

+ 56 - 30
src/main/java/org/codelibs/fess/util/QueryStringBuilder.java

@@ -28,6 +28,10 @@ import org.codelibs.fess.mylasta.direction.FessConfig;
 
 
 public class QueryStringBuilder {
 public class QueryStringBuilder {
 
 
+    private static final String OR_ALT = "||";
+
+    private static final String OR = " OR ";
+
     private SearchRequestParams params;
     private SearchRequestParams params;
 
 
     protected String quote(final String value) {
     protected String quote(final String value) {
@@ -42,35 +46,15 @@ public class QueryStringBuilder {
         final int maxQueryLength = fessConfig.getQueryMaxLengthAsInteger().intValue();
         final int maxQueryLength = fessConfig.getQueryMaxLengthAsInteger().intValue();
         final StringBuilder queryBuf = new StringBuilder(255);
         final StringBuilder queryBuf = new StringBuilder(255);
 
 
-        final Map<String, String[]> conditions = params.getConditions();
-        if (params.hasConditionQuery()) {
-            appendConditions(queryBuf, conditions);
-        } else {
-            final String query = params.getQuery();
-            if (StringUtil.isNotBlank(query)) {
-                if (ComponentUtil.hasRelatedQueryHelper()) {
-                    final RelatedQueryHelper relatedQueryHelper = ComponentUtil.getRelatedQueryHelper();
-                    final String[] relatedQueries = relatedQueryHelper.getRelatedQueries(query);
-                    if (relatedQueries.length == 0) {
-                        queryBuf.append(query);
-                    } else {
-                        queryBuf.append('(');
-                        queryBuf.append(quote(query));
-                        for (final String s : relatedQueries) {
-                            queryBuf.append(" OR ");
-                            queryBuf.append(quote(s));
-                        }
-                        queryBuf.append(')');
-                    }
-                } else {
-                    queryBuf.append(query);
-                }
-            }
+        final String query = buildBaseQuery();
+        if (StringUtil.isNotBlank(query)) {
+            queryBuf.append(query);
         }
         }
 
 
         stream(params.getExtraQueries()).of(
         stream(params.getExtraQueries()).of(
-                stream -> stream.filter(q -> StringUtil.isNotBlank(q) && q.length() <= maxQueryLength).forEach(
-                        q -> queryBuf.append(' ').append(q)));
+                stream -> stream.filter(q -> StringUtil.isNotBlank(q) && q.length() <= maxQueryLength).forEach(q -> {
+                    appendQuery(queryBuf, q);
+                }));
 
 
         stream(params.getFields()).of(stream -> stream.forEach(entry -> {
         stream(params.getFields()).of(stream -> stream.forEach(entry -> {
             final String key = entry.getKey();
             final String key = entry.getKey();
@@ -86,7 +70,7 @@ public class QueryStringBuilder {
                     if (first) {
                     if (first) {
                         first = false;
                         first = false;
                     } else {
                     } else {
-                        queryBuf.append(" OR ");
+                        queryBuf.append(OR);
                     }
                     }
                     queryBuf.append(key).append(":\"").append(value).append('\"');
                     queryBuf.append(key).append(":\"").append(value).append('\"');
                 }
                 }
@@ -97,6 +81,47 @@ public class QueryStringBuilder {
         return queryBuf.toString().trim();
         return queryBuf.toString().trim();
     }
     }
 
 
+    protected void appendQuery(final StringBuilder queryBuf, String q) {
+        final boolean exists = q.indexOf(OR) != -1 || q.indexOf(OR_ALT) != -1;
+        queryBuf.append(' ');
+        if (exists) {
+            queryBuf.append('(');
+        }
+        queryBuf.append(q);
+        if (exists) {
+            queryBuf.append(')');
+        }
+    }
+
+    protected String buildBaseQuery() {
+        final StringBuilder queryBuf = new StringBuilder(255);
+        if (params.hasConditionQuery()) {
+            appendConditions(queryBuf, params.getConditions());
+        } else {
+            final String query = params.getQuery();
+            if (StringUtil.isNotBlank(query)) {
+                if (ComponentUtil.hasRelatedQueryHelper()) {
+                    final RelatedQueryHelper relatedQueryHelper = ComponentUtil.getRelatedQueryHelper();
+                    final String[] relatedQueries = relatedQueryHelper.getRelatedQueries(query);
+                    if (relatedQueries.length == 0) {
+                        appendQuery(queryBuf, query);
+                    } else {
+                        queryBuf.append('(');
+                        queryBuf.append(quote(query));
+                        for (final String s : relatedQueries) {
+                            queryBuf.append(OR);
+                            queryBuf.append(quote(s));
+                        }
+                        queryBuf.append(')');
+                    }
+                } else {
+                    appendQuery(queryBuf, query);
+                }
+            }
+        }
+        return queryBuf.toString().trim();
+    }
+
     protected void appendConditions(final StringBuilder queryBuf, final Map<String, String[]> conditions) {
     protected void appendConditions(final StringBuilder queryBuf, final Map<String, String[]> conditions) {
         if (conditions == null) {
         if (conditions == null) {
             return;
             return;
@@ -116,9 +141,10 @@ public class QueryStringBuilder {
         stream(conditions.get(SearchRequestParams.AS_OQ)).of(
         stream(conditions.get(SearchRequestParams.AS_OQ)).of(
                 stream -> stream.filter(q -> StringUtil.isNotBlank(q) && q.length() <= maxQueryLength).forEach(
                 stream -> stream.filter(q -> StringUtil.isNotBlank(q) && q.length() <= maxQueryLength).forEach(
                         oq -> split(oq, " ").get(
                         oq -> split(oq, " ").get(
-                                s -> s.filter(StringUtil::isNotBlank).reduce(
-                                        (q1, q2) -> escape(q1, "(", ")") + " OR " + escape(q2, "(", ")"))).ifPresent(
-                                q -> queryBuf.append(" (").append(q).append(')'))));
+                                s -> s.filter(StringUtil::isNotBlank).reduce((q1, q2) -> escape(q1, "(", ")") + OR + escape(q2, "(", ")")))
+                                .ifPresent(q -> {
+                                    appendQuery(queryBuf, q);
+                                })));
         stream(conditions.get(SearchRequestParams.AS_NQ)).of(
         stream(conditions.get(SearchRequestParams.AS_NQ)).of(
                 stream -> stream.filter(q -> StringUtil.isNotBlank(q) && q.length() <= maxQueryLength).forEach(
                 stream -> stream.filter(q -> StringUtil.isNotBlank(q) && q.length() <= maxQueryLength).forEach(
                         eq -> {
                         eq -> {

+ 2 - 2
src/test/java/org/codelibs/fess/util/QueryStringBuilderTest.java

@@ -52,9 +52,9 @@ public class QueryStringBuilderTest extends UnitFessTestCase {
     public void test_conditions_oq() {
     public void test_conditions_oq() {
         final String k = "oq";
         final String k = "oq";
         assertEquals("", getAsQuery(Collections.singletonMap(k, new String[] { "" })));
         assertEquals("", getAsQuery(Collections.singletonMap(k, new String[] { "" })));
-        assertEquals("(aaa)", getAsQuery(Collections.singletonMap(k, new String[] { "aaa" })));
+        assertEquals("aaa", getAsQuery(Collections.singletonMap(k, new String[] { "aaa" })));
         assertEquals("(aaa OR bbb)", getAsQuery(Collections.singletonMap(k, new String[] { "aaa bbb" })));
         assertEquals("(aaa OR bbb)", getAsQuery(Collections.singletonMap(k, new String[] { "aaa bbb" })));
-        assertEquals("(aaa OR bbb) (ccc)", getAsQuery(Collections.singletonMap(k, new String[] { "aaa bbb", "ccc" })));
+        assertEquals("(aaa OR bbb) ccc", getAsQuery(Collections.singletonMap(k, new String[] { "aaa bbb", "ccc" })));
         assertEquals("(aaa OR bbb) (ccc OR ddd)", getAsQuery(Collections.singletonMap(k, new String[] { "aaa bbb", "ccc ddd" })));
         assertEquals("(aaa OR bbb) (ccc OR ddd)", getAsQuery(Collections.singletonMap(k, new String[] { "aaa bbb", "ccc ddd" })));
         assertEquals("(aaa OR bbb)", getAsQuery("111", Collections.singletonMap(k, new String[] { "aaa bbb" })));
         assertEquals("(aaa OR bbb)", getAsQuery("111", Collections.singletonMap(k, new String[] { "aaa bbb" })));
     }
     }