Spring Data Solr
  1. Spring Data Solr
  2. DATASOLR-72

Dynamically create SolrServer for Cores read from solr core admin

    Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: 1.2 GA (Dijkstra)
    • Component/s: Core
    • Labels:
      None

      Description

      read solr cores from CoreAdmin and create a MulticoreSolrServerFactory with this information.

      CoreAdminRequest request = new CoreAdminRequest();
      request.setAction(CoreAdminAction.STATUS);
      CoreAdminResponse cores = request.process(solrServer);
      
      // List of the cores
      List<String> coreList = new ArrayList<String>();
      for (int i = 0; i < cores.getCoreStatus().size(); i++) {
          coreList.add(cores.getCoreStatus().getName(i));
      }
      
      SolrServerFatory factory = new MulticoreSolrServerFactory(SolrServer, coreList);
      

      when calling operation on SolrTemplate use type information to retrieve SolrServer for core defined via @SolrDocument.

      SolrServer = factory.getSolrServer(BeanForCollection1.class)
      
      @SolrDocument(core = "collection1")
      public class BeanForCollection1 {
       ....
      

        Issue Links

          Activity

          Hide
          Marco Fago added a comment -

          Basically I would need a different approach where you can dinamically select the core you need, maybe using a @SolrCore annotation:

           
          SolrServer = factory.getSolrServer(BeanForCollection1.class)
          
          @SolrDocument
          public class BeanForCollection1 {
          
             @SolrCore
             private String core;
           ....
          
          
          Show
          Marco Fago added a comment - Basically I would need a different approach where you can dinamically select the core you need, maybe using a @SolrCore annotation: SolrServer = factory.getSolrServer(BeanForCollection1.class) @SolrDocument public class BeanForCollection1 { @SolrCore private String core; ....
          Hide
          Christoph Strobl added a comment -

          Hi Marco,
          thank you for your input. will take that into account.

          Show
          Christoph Strobl added a comment - Hi Marco, thank you for your input. will take that into account.
          Hide
          Christoph Strobl added a comment -

          Hi,
          took some time but would like to get some input from you on this, which is more related to DATASOLR-82 but concerns this issue as well.

          actually I'm thinking of MulticoreSolrServerFactory offering SolrServer getSolrServer(String core) and SolrServer getSolrServer(Class<?> clazz).

          The factory itself will have to have a reference to a SolrServer holding baseUrl.
          When calling any of the two get methods above, the factory would check if there is already a SolrServer instance registered for the given core and if not create a new one copying settings of the reference one, as well as setting the url for the core.

          <solr:solr-server id="solrServer" url="http://127.0.0.1:8983/solr" />
            
          <bean id="solrServerFactory" class="org.springframework.data.solr.server.support.MulticoreSolrServerFactory">
            <constructor-arg ref="solrServer" />
          </bean>
          
          @SolrDocument("core1")
          class BeanForCore1 {
            //....
          }
          
          //get a instace by corename
          SolrServer core0 = multicoreSolrServerFactory.getSolrServer("core0");
          
          //get instance for class
          SolrServer core1 = multicoreSolrServerFactory.getSolrServer(BeanForCore1.class);
          
          Show
          Christoph Strobl added a comment - Hi, took some time but would like to get some input from you on this, which is more related to DATASOLR-82 but concerns this issue as well. actually I'm thinking of MulticoreSolrServerFactory offering SolrServer getSolrServer(String core) and SolrServer getSolrServer(Class<?> clazz) . The factory itself will have to have a reference to a SolrServer holding baseUrl. When calling any of the two get methods above, the factory would check if there is already a SolrServer instance registered for the given core and if not create a new one copying settings of the reference one, as well as setting the url for the core. <solr:solr-server id= "solrServer" url= "http://127.0.0.1:8983/solr" /> <bean id= "solrServerFactory" class= "org.springframework.data.solr.server.support.MulticoreSolrServerFactory" > <constructor-arg ref= "solrServer" /> </bean> @SolrDocument( "core1" ) class BeanForCore1 { //.... } //get a instace by corename SolrServer core0 = multicoreSolrServerFactory.getSolrServer( "core0" ); //get instance for class SolrServer core1 = multicoreSolrServerFactory.getSolrServer(BeanForCore1.class);
          Hide
          Marco Fago added a comment -

          I think that the proposed solution does not allow to change dynamically the core, since the core name is hardcoded in the class definition. Probably my solution was misleading, in the sense that I meant

          @SolrCore private String core;
          

          as a bidirectional injected variable (from the object to the container and back).
          This would allow one to define at runtime which core the document is related to.

          Show
          Marco Fago added a comment - I think that the proposed solution does not allow to change dynamically the core, since the core name is hardcoded in the class definition. Probably my solution was misleading, in the sense that I meant @SolrCore private String core; as a bidirectional injected variable (from the object to the container and back). This would allow one to define at runtime which core the document is related to.
          Hide
          Christoph Strobl added a comment -

          Hi,
          using MulticoreSolrServerFactory.getSolrServer(String coreName) would allow to select the core by its name.

          SolrServer solrServer = multicoreSolrServerFactory.getSolrServer(bean.getCore());
          

          Would this fit your needs?

          Show
          Christoph Strobl added a comment - Hi, using MulticoreSolrServerFactory.getSolrServer(String coreName) would allow to select the core by its name. SolrServer solrServer = multicoreSolrServerFactory.getSolrServer(bean.getCore()); Would this fit your needs?
          Hide
          Marco Fago added a comment -

          Yes it could. But what about SolrCrudRepository? How would it be possible to specify which core use with SolrCrudRepository?

          Show
          Marco Fago added a comment - Yes it could. But what about SolrCrudRepository? How would it be possible to specify which core use with SolrCrudRepository?
          Hide
          Christoph Strobl added a comment -

          This a hard to answer as the CrudRepository is ment to deal with only one type each.
          What I could actually think of is using multicoreSolrServerFactory within multiple SolrTemplates specific to a single core, and instanciate Repository manually. But maybe I just do not see the forest for the trees right now.

          Show
          Christoph Strobl added a comment - This a hard to answer as the CrudRepository is ment to deal with only one type each. What I could actually think of is using multicoreSolrServerFactory within multiple SolrTemplates specific to a single core, and instanciate Repository manually. But maybe I just do not see the forest for the trees right now.
          Hide
          Marco Fago added a comment - - edited

          What if multicoreSolrServerFactory accepts only the base url (with no core specification) and a parameter telling what attribute in the document specifies the core?
          F.i.

          <solr:solr-server id="solrServer" url="http://127.0.0.1:8983/solr" />
          <bean id="solrServerFactory" class="org.springframework.data.solr.server.support.MulticoreSolrServerFactory">
            <constructor-arg ref="solrServer" />
            <property name="documentCoreAttribute" value="core"/>
            <property name="defaultCore" value="core0"/>
          </bean>
          
          @SolrDocument
          public class BeanForCollection1 {
          
             @SolrCore
             private String core;
           ....
          }
          

          Probably in this case the solrServer scope should change (I'm not sure it can be a singleton).
          The same result would be achieved using the @SolrCore annotation in the solr document.
          Would it help with Solr repositories?

          Show
          Marco Fago added a comment - - edited What if multicoreSolrServerFactory accepts only the base url (with no core specification) and a parameter telling what attribute in the document specifies the core? F.i. <solr:solr-server id= "solrServer" url= "http: //127.0.0.1:8983/solr" /> <bean id= "solrServerFactory" class= "org.springframework.data.solr.server.support.MulticoreSolrServerFactory" > <constructor-arg ref= "solrServer" /> <property name= "documentCoreAttribute" value= "core" /> <property name= "defaultCore" value= "core0" /> </bean> @SolrDocument public class BeanForCollection1 { @SolrCore private String core; .... } Probably in this case the solrServer scope should change (I'm not sure it can be a singleton). The same result would be achieved using the @SolrCore annotation in the solr document. Would it help with Solr repositories?

            People

            • Assignee:
              Christoph Strobl
              Reporter:
              Christoph Strobl
            • Votes:
              2 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated: