2 Replies Latest reply on Jun 22, 2015 10:19 AM by Geoffrey Gershaw

    Infinispan Query DSL question on version 7.2.2

    Geoffrey Gershaw Newbie

      Hello All,

       

      I am a newbie to infinispan  and am trying to do slightly more complicated query than the docs or book mention. I might have missed it though. If so, I apologize. I am using infinispan as a local cache.

       

      Lets say, I am storing Runner, below,  into a cache. I realize ageBracket should be an enum, but lets pretend you don't know the ageBrackets at design time. For each age bracket, I would like to retrieve the first place Runner who has not cheated. If they have not cheated, cheatedReasonTxt will be null.

       

      If this were in an RDB, I believe the SQL would be

       

      SELECT fullName, min(finishingTime)

      FROM RunnerResults i WHERE

      i.cheatedReasonTxt IS NOT NULL

      GROUP BY ageBracket

       

      I appreciate any advice you can provide on how to structure this query. Additionally, when I try to use the isNull() method  on cheatedReasonTxt, I get the following exception, which is at the bottom of this message. I don't understand why you can't check if a string field is null

       

       

      Thanks

       

      public class Runner implements Serializable {

        private static final long serialVersionUID = 1018490206459365389L;

        @Field
        private final String SSN;

        @Field(analyze= Analyze.NO)

        private final String fullName;

        @Field(analyze= Analyze.NO)

        private final String cheatedReasonTxt;

        @Field(analyze=Analyze.NO)

        private final String ageBracket;

        @Field(analyze=Analyze.NO)

        private final Date finishingTime;

       

        public Runner(String SSN, String fullName, String cheatedReasonTxt, String ageBracket, Date finishingTime) {

        this.SSN = SSN;

        this.fullName = fullName;

        this.cheatedReasonTxt = cheatedReasonTxt;

        this.ageBracket = ageBracket;

        this.finishingTime = finishingTime;

        }

       

        public Date getFinishingTime() {return finishingTime;}

        public String getSSN() {return SSN;}

        public String getCheatedReasonTxt() {return cheatedReasonTxt;}

        public String getFullName() {return fullName;}

        public String getAgeBracket() {return ageBracket;}

      }

       

       

      org.hibernate.search.exception.SearchException: Search parameter on field rejectReason could not be converted. Are the parameter and the field of the same type?Alternatively, apply the ignoreFieldBridge() option to pass String parameters

        at org.hibernate.search.query.dsl.impl.Helper.getAllTermsFromText(Helper.java:68)

        at org.hibernate.search.query.dsl.impl.ConnectedMultiFieldsTermQueryBuilder.getAllTermsFromText(ConnectedMultiFieldsTermQueryBuilder.java:172)

        at org.hibernate.search.query.dsl.impl.ConnectedMultiFieldsTermQueryBuilder.createQuery(ConnectedMultiFieldsTermQueryBuilder.java:89)

        at org.hibernate.search.query.dsl.impl.ConnectedMultiFieldsTermQueryBuilder.createQuery(ConnectedMultiFieldsTermQueryBuilder.java:64)

        at org.hibernate.hql.lucene.internal.builder.predicate.LuceneIsNullPredicate.getQuery(LuceneIsNullPredicate.java:44)

        at org.hibernate.hql.lucene.internal.builder.predicate.LuceneIsNullPredicate.getQuery(LuceneIsNullPredicate.java:33)

        at org.hibernate.hql.lucene.internal.builder.predicate.LuceneConjunctionPredicate.getQuery(LuceneConjunctionPredicate.java:54)

        at org.hibernate.hql.lucene.internal.builder.predicate.LuceneConjunctionPredicate.getQuery(LuceneConjunctionPredicate.java:34)

        at org.hibernate.hql.lucene.internal.builder.predicate.LuceneRootPredicate.getQuery(LuceneRootPredicate.java:42)

        at org.hibernate.hql.lucene.internal.builder.predicate.LuceneRootPredicate.getQuery(LuceneRootPredicate.java:32)

        at org.hibernate.hql.ast.spi.SingleEntityQueryBuilder.build(SingleEntityQueryBuilder.java:174)

        at org.hibernate.hql.lucene.internal.LuceneQueryRendererDelegate.getResult(LuceneQueryRendererDelegate.java:91)

        at org.hibernate.hql.lucene.LuceneProcessingChain.getResult(LuceneProcessingChain.java:147)

        at org.hibernate.hql.lucene.LuceneProcessingChain.getResult(LuceneProcessingChain.java:49)

        at org.hibernate.hql.QueryParser.parseQuery(QueryParser.java:89)

        at org.infinispan.query.dsl.embedded.impl.QueryEngine.transformJpaToLucene(QueryEngine.java:141)

        at org.infinispan.query.dsl.embedded.impl.QueryEngine.buildLuceneQuery(QueryEngine.java:105)

        at org.infinispan.query.dsl.embedded.impl.EmbeddedLuceneQueryBuilder.build(EmbeddedLuceneQueryBuilder.java:34)

        at org.infinispan.query.dsl.embedded.impl.EmbeddedLuceneQueryBuilder.build(EmbeddedLuceneQueryBuilder.java:17)

        at com.csg.ib.fid.credit.etrading.madar.cache.NeptuneAdapterIoiMsgCache.read(NeptuneAdapterIoiMsgCache.java:113)

        at com.csg.ib.fid.credit.etrading.madar.cache.NeptuneAdapterIoiMsgCacheTest.testRead(NeptuneAdapterIoiMsgCacheTest.java:92)

        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)

        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)

        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)

        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)

        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)

        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)

        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)

        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)

        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)

        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)

        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)

        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)

        at org.junit.runners.ParentRunner.run(ParentRunner.java:309)

        at org.junit.runner.JUnitCore.run(JUnitCore.java:160)

        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)

        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)

        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)

        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

        • 1. Re: Infinispan Query DSL question on version 7.2.2
          Gustavo Fernandes Apprentice

          You'll need to use Lucene directly in order to achieve what you want. It'd look like that:

           

          // Obtain index searcher
          IndexReader indexReader = Search.getSearchManager(cache).getSearchFactory().getIndexReaderAccessor().open(Runner.class);

          IndexSearcher searcher = new IndexSearcher(indexReader);

           

          // Lucene query for those that not cheated
          BooleanQuery notCheatedQuery = new BooleanQuery();

          notCheatedQuery.add(new MatchAllDocsQuery(), BooleanClause.Occur.SHOULD);

          notCheatedQuery.add(new TermRangeQuery("cheatedReasonTxt", null, null, true, true), BooleanClause.Occur.MUST_NOT);

           

          // Group by ageBracket, sort inside each group by 'finishingTime' and 'fullName'
          GroupingSearch groupingSearch = new GroupingSearch("ageBracket");

          groupingSearch.setSortWithinGroup(new Sort(new SortField("finishingTime", SortField.Type.LONG), new SortField("fullName", SortField.Type.STRING)));

          groupingSearch.setFillSortFields(true);

           

          // Execute group query extracting top 100 groups
          TopGroups<Object> topGroups = groupingSearch.search(searcher, notCheatedQuery, 0, 100);

           

          // Collect results
          Map<String, Date> results = new HashMap<>();

          for (int i = 0; i < topGroups.groups.length; i++) {

             // Each groupDoc will hold a certain age bracket
             GroupDocs<Object> group = topGroups.groups[i];

             // Get first document in the group (smaller finish time)
             FieldDoc scoreDoc = (FieldDoc) group.scoreDocs[0];

             // Extract time and name
             Date minTime = new Date(Long.valueOf(scoreDoc.fields[0].toString()));

             String fullName = ((BytesRef) scoreDoc.fields[1]).utf8ToString();

            results.put(fullName, minTime);

          }

           

          The map would hold the runner that finished first in his age band (that not cheated) followed by his time.

          • 2. Re: Infinispan Query DSL question on version 7.2.2
            Geoffrey Gershaw Newbie

            Hi Gustavo,

             

            Thanks for taking the time to reply to my question. I appreciate it. I would like to have the Runner returned from the query. Not just the sort fields. Please see below.

             

            Map<Runner, Date> results = new HashMap<>();

            for (int i = 0; i < topGroups.groups.length; i++) {

             

            }

             

            Any idea how to do this?

             

            Thanks