Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.4.1
    • Fix Version/s: 4.0-ALPHA
    • Component/s: search
    • Labels:
      None

      Description

      Add an if() function which will enable conditional function queries.

      The function could be modeled after a spreadsheet if function (e.g: http://wiki.services.openoffice.org/wiki/Documentation/How_Tos/Calc:_IF_function)

      IF(test; value1; value2) where:
      test is or refers to a logical value or expression that returns a logical value (TRUE or FALSE).
      value1 is the value that is returned by the function if test yields TRUE.
      value2 is the value that is returned by the function if test yields FALSE.

      If value2 is omitted it is assumed to be FALSE; if value1 is also omitted it is assumed to be TRUE.

      Example use:
      if(color=="red"; 100; if(color=="green"; 50; 25))
      This function will check the document field "color", and if it is "red" return 100, if it is "green" return 50, else return 25.

      1. SOLR-2136.patch
        47 kB
        Yonik Seeley
      2. SOLR-2136.patch
        25 kB
        Yonik Seeley

        Issue Links

          Activity

          Hide
          William Bell added a comment - - edited

          How about on fq? I want to run 1 query and if the numFound > 0, then return that fq, otherwise skip it. This was inspired by your test case:

          "

          {!frange l=1 u=1}

          if(exists("f"),1,0)"

          Ok,
          f=specialties:Cardiologist

          "fq=if(numfound(query("+f+")),f,*:*)" 
          

          Will something like that work?

          Show
          William Bell added a comment - - edited How about on fq? I want to run 1 query and if the numFound > 0, then return that fq, otherwise skip it. This was inspired by your test case: " {!frange l=1 u=1} if(exists(" f "),1,0)" Ok, f=specialties:Cardiologist "fq= if (numfound(query(" +f+ ")),f,*:*)" Will something like that work?
          Hide
          William Bell added a comment -

          Can we add multiValued field support?

          Show
          William Bell added a comment - Can we add multiValued field support?
          Hide
          Yonik Seeley added a comment -

          Thanks Koji, I just committed a fix for this cut'n'paste error.

          Show
          Yonik Seeley added a comment - Thanks Koji, I just committed a fix for this cut'n'paste error.
          Hide
          Koji Sekiguchi added a comment -

          I've met a strange behavior. With empty index, start example solr. Then hit:

          http://localhost:8983/solr/select/?q=

          {!func}

          if(exists(f1_b),10,20)&debug=results

          you got an empty xml as expected. Then hit the above URL again, you got the following exception:

          SEVERE: java.lang.ClassCastException: org.apache.solr.search.ValueSourceParser$60$1 cannot be cast to org.apache.solr.search.function.SingleFunction
          	at org.apache.solr.search.function.SimpleBoolFunction.equals(SimpleBoolFunction.java:66)
          	at org.apache.solr.search.function.IfFunction.equals(IfFunction.java:137)
          	at org.apache.solr.search.function.FunctionQuery.equals(FunctionQuery.java:202)
          	at org.apache.solr.search.QueryResultKey.equals(QueryResultKey.java:78)
          	at java.util.HashMap.getEntry(HashMap.java:349)
          	at java.util.LinkedHashMap.get(LinkedHashMap.java:280)
          	at org.apache.solr.search.LRUCache.get(LRUCache.java:129)
          	at org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:991)
          	at org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:346)
          	at org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:441)
          	at org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:239)
          	at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:129)
          	at org.apache.solr.core.SolrCore.execute(SolrCore.java:1308)
          	at org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:353)
          	at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:248)
          	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)
          	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:399)
          	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
          	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
          	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
          	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450)
          	at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
          	at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
          	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
          	at org.mortbay.jetty.Server.handle(Server.java:326)
          	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
          	at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:928)
          	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:549)
          	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
          	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
          	at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
          	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
          
          Show
          Koji Sekiguchi added a comment - I've met a strange behavior. With empty index, start example solr. Then hit: http://localhost:8983/solr/select/?q= {!func} if(exists(f1_b),10,20)&debug=results you got an empty xml as expected. Then hit the above URL again, you got the following exception: SEVERE: java.lang.ClassCastException: org.apache.solr.search.ValueSourceParser$60$1 cannot be cast to org.apache.solr.search.function.SingleFunction at org.apache.solr.search.function.SimpleBoolFunction.equals(SimpleBoolFunction.java:66) at org.apache.solr.search.function.IfFunction.equals(IfFunction.java:137) at org.apache.solr.search.function.FunctionQuery.equals(FunctionQuery.java:202) at org.apache.solr.search.QueryResultKey.equals(QueryResultKey.java:78) at java.util.HashMap.getEntry(HashMap.java:349) at java.util.LinkedHashMap.get(LinkedHashMap.java:280) at org.apache.solr.search.LRUCache.get(LRUCache.java:129) at org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:991) at org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:346) at org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:441) at org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:239) at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:129) at org.apache.solr.core.SolrCore.execute(SolrCore.java:1308) at org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:353) at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:248) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:399) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450) at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230) at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at org.mortbay.jetty.Server.handle(Server.java:326) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:928) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:549) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
          Hide
          Yonik Seeley added a comment -

          Is it possible to have exists() work on multi valued fields too without crashing?

          Not currently... but note that exists() works on subqueries too, not just fields.

          So a slow way to do it would be

            ...exists(query($qq))&qq=myfield:[* TO *]
          

          Or a faster workaround could be to index a special EXISTS token or EMPTY token and do

            ...exists(query($qq))&qq=myfield:EXISTS
          

          See the test code in TestFunctionQuery for an easy way to use pseudo-fields to test this stuff.

          Show
          Yonik Seeley added a comment - Is it possible to have exists() work on multi valued fields too without crashing? Not currently... but note that exists() works on subqueries too, not just fields. So a slow way to do it would be ...exists(query($qq))&qq=myfield:[* TO *] Or a faster workaround could be to index a special EXISTS token or EMPTY token and do ...exists(query($qq))&qq=myfield:EXISTS See the test code in TestFunctionQuery for an easy way to use pseudo-fields to test this stuff.
          Hide
          Jan Høydahl added a comment -

          Great Yonik!
          Is it possible to have exists() work on multi valued fields too without crashing?

          Show
          Jan Høydahl added a comment - Great Yonik! Is it possible to have exists() work on multi valued fields too without crashing?
          Hide
          Yonik Seeley added a comment -

          Here's an update with tests that builds out more boolean support, including true/false constants. This also adds xor() and def() functions.

          def is short for default and yields the first value where exists()==true. Thus
          def(myfield, 1.0) is equivalent to if(exists(myfield),myfield,1.0)

          I think this is ready to commit!

          Show
          Yonik Seeley added a comment - Here's an update with tests that builds out more boolean support, including true/false constants. This also adds xor() and def() functions. def is short for default and yields the first value where exists()==true. Thus def(myfield, 1.0) is equivalent to if(exists(myfield),myfield,1.0) I think this is ready to commit!
          Hide
          Yonik Seeley added a comment -

          Here's a first cut at adding boolean support to function queries, if(), exists(), and(), or(), and not().

          No tests yet.

          Show
          Yonik Seeley added a comment - Here's a first cut at adding boolean support to function queries, if(), exists(), and(), or(), and not(). No tests yet.
          Hide
          Nils Weber added a comment -

          any news on that one and/or on SOLR-2137 yet?

          regards JC

          Show
          Nils Weber added a comment - any news on that one and/or on SOLR-2137 yet? regards JC

            People

            • Assignee:
              Unassigned
              Reporter:
              Jan Høydahl
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development