You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by so...@apache.org on 2020/06/03 19:14:04 UTC

[lucene-solr] 35/47: SOLR-14419: adding {param:ref} to Query DSL

This is an automated email from the ASF dual-hosted git repository.

sokolov pushed a commit to branch jira/lucene-8962
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 6e2cdcca792f330a287eba0a6642f43a35032c43
Author: Mikhail Khludnev <mk...@apache.org>
AuthorDate: Sun Apr 26 23:04:00 2020 +0300

    SOLR-14419: adding {param:ref} to Query DSL
---
 solr/CHANGES.txt                                   |  2 +
 .../solr/request/json/JsonQueryConverter.java      | 50 ++++++++++++++--------
 .../apache/solr/search/json/TestJsonRequest.java   | 39 ++++++++++++++++-
 3 files changed, 73 insertions(+), 18 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index aeb7945..28d8552 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -125,6 +125,8 @@ Improvements
   themselves. The collection hints are pushed down to the policy engine so operations for non-matching collections
   are not computed at all. (ab, shalin)
 
+* SOLR-14419: json.queries as well as other parameters might be referred via {"param":"ref"} in Query DSL (Mikhail Khludnev)
+
 Optimizations
 ---------------------
 * SOLR-8306: Do not collect expand documents when expand.rows=0 (Marshall Sanders, Amelia Henderson)
diff --git a/solr/core/src/java/org/apache/solr/request/json/JsonQueryConverter.java b/solr/core/src/java/org/apache/solr/request/json/JsonQueryConverter.java
index 22e15c7..e736750 100644
--- a/solr/core/src/java/org/apache/solr/request/json/JsonQueryConverter.java
+++ b/solr/core/src/java/org/apache/solr/request/json/JsonQueryConverter.java
@@ -98,6 +98,18 @@ class JsonQueryConverter {
           qtype = map.keySet().iterator().next();
           // FUTURE: might want to recurse here instead to handle nested tags (and add tagName as a parameter?)
         }
+      } else {
+        if (qtype.equals("param")) {
+          boolean toplevel;
+          if (toplevel=(builder.length() == 0)) {
+            builder.append("{!v=");  
+          }
+          builder.append("$").append(map.get("param"));
+          if (toplevel) {
+            builder.append("}");
+          }
+          return;
+        }
       }
 
       StringBuilder subBuilder = useSubBuilder ? new StringBuilder() : builder;
@@ -114,26 +126,30 @@ class JsonQueryConverter {
         builder.append('$').append(putParam(subBuilder.toString(), additionalParams));
       }
     } else {
-      for (Map.Entry<String, Object> entry : map.entrySet()) {
-        String key = entry.getKey();
-        if (entry.getValue() instanceof List) {
-          if (key.equals("query")) {
-            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
-                "Error when parsing json query, value of query field should not be a list, found : " + entry.getValue());
-          }
-          List l = (List) entry.getValue();
-          for (Object subVal : l) {
+      if(map.size()==1 && map.keySet().iterator().next().equals("param")) {
+        builder.append("v").append("=$").append(map.get("param")).append(" ");
+      } else {
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+          String key = entry.getKey();
+          if (entry.getValue() instanceof List) {
+            if (key.equals("query")) {
+              throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
+                  "Error when parsing json query, value of query field should not be a list, found : " + entry.getValue());
+            }
+            List l = (List) entry.getValue();
+            for (Object subVal : l) {
+              builder.append(key).append("=");
+              buildLocalParams(builder, subVal, true, additionalParams);
+              builder.append(" ");
+            }
+          } else {
+            if (key.equals("query")) {
+              key = "v";
+            }
             builder.append(key).append("=");
-            buildLocalParams(builder, subVal, true, additionalParams);
+            buildLocalParams(builder, entry.getValue(), true, additionalParams);
             builder.append(" ");
           }
-        } else {
-          if (key.equals("query")) {
-            key = "v";
-          }
-          builder.append(key).append("=");
-          buildLocalParams(builder, entry.getValue(), true, additionalParams);
-          builder.append(" ");
         }
       }
     }
diff --git a/solr/core/src/test/org/apache/solr/search/json/TestJsonRequest.java b/solr/core/src/test/org/apache/solr/search/json/TestJsonRequest.java
index 2ab19e9..9451ddf 100644
--- a/solr/core/src/test/org/apache/solr/search/json/TestJsonRequest.java
+++ b/solr/core/src/test/org/apache/solr/search/json/TestJsonRequest.java
@@ -24,6 +24,7 @@ import org.apache.solr.JSONTestUtil;
 import org.apache.solr.SolrTestCaseHS;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.search.CaffeineCache;
 import org.apache.solr.search.DocSet;
@@ -179,7 +180,7 @@ public class TestJsonRequest extends SolrTestCaseHS {
         , "response/docs==[{id:'5', x:5.5},{id:'4', x:5.5}]"
     );
 
-
+    doParamRefDslTest(client);
 
     // test templating before parsing JSON
     client.testJQ( params("json","${OPENBRACE} query:'cat_s:A' ${CLOSEBRACE}", "json","${OPENBRACE} filter:'where_s:NY'${CLOSEBRACE}",  "OPENBRACE","{", "CLOSEBRACE","}")
@@ -407,6 +408,42 @@ public class TestJsonRequest extends SolrTestCaseHS {
 
   }
 
+  private static void doParamRefDslTest(Client client) throws Exception {
+    // referencing in dsl                //nestedqp
+    client.testJQ( params("json","{query: {query:  {param:'ref1'}}}", "ref1","{!field f=cat_s}A")
+        , "response/numFound==2"
+    );   
+    // referencing json string param
+    client.testJQ( params("json", random().nextBoolean()  ? 
+            "{query:{query:{param:'ref1'}}}"  // nestedqp
+           : "{query: {query: {query:{param:'ref1'}}}}",  // nestedqp, v local param  
+          "json",random().nextBoolean() 
+              ? "{params:{ref1:'{!field f=cat_s}A'}}" // string param  
+              : "{queries:{ref1:{field:{f:cat_s,query:A}}}}" ) // qdsl
+        , "response/numFound==2"
+    );
+    {                                                     // shortest top level ref
+      final ModifiableSolrParams params = params("json","{query:{param:'ref1'}}");
+      if (random().nextBoolean()) {
+        params.add("ref1","cat_s:A"); // either to plain string
+      } else {
+        params.add("json","{queries:{ref1:{field:{f:cat_s,query:A}}}}");// or to qdsl
+      }
+      client.testJQ( params, "response/numFound==2");
+    }  // ref in bool must
+    client.testJQ( params("json","{query:{bool: {must:[{param:fq1},{param:fq2}]}}}",
+        "json","{params:{fq1:'cat_s:A', fq2:'where_s:NY'}}", "json.fields", "id")
+        , "response/docs==[{id:'1'}]"
+    );// referencing dsl&strings from filters objs&array
+    client.testJQ( params("json.filter","{param:fq1}","json.filter","{param:fq2}",
+        "json", random().nextBoolean() ?
+             "{queries:{fq1:{lucene:{query:'cat_s:A'}}, fq2:{lucene:{query:'where_s:NY'}}}}" : 
+             "{params:{fq1:'cat_s:A', fq2:'where_s:NY'}}", 
+        "json.fields", "id", "q", "*:*")
+        , "response/docs==[{id:'1'}]"
+    );
+  }
+
   private static void testFilterCachingLocally(Client client) throws Exception {
     if(client.getClientProvider()==null) {
       final SolrQueryRequest request = req();