2012-12-18 54 views
1

我想盡可能少地使用類,所以我想構建JAXB和Solr帶註釋的POJO,正如您猜測的那樣,可以使用XML,編組它到公司對象併爲其編制索引。使用帶有JAXB和Solr註解的嵌套類的POJO

我對編組沒有任何問題 - 公司對象被構造得很好。我遇到的問題是如何註釋公司POJO創建一個多值字符串解析字段

的XML看起來是這樣的:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<company> 
    <registryNumber>5226805000</registryNumber> 
    <names> 
     <name>name1</name> 
     <name>name2</name> 
    </names> 
</company> 

,併爲公司POJO我目前可憐的企圖看起來像:

@XmlRootElement(name = "company") 
public class Company { 

    public Company() {} 

    @XmlElement 
    @Field("id") 
    public String registryNumber; 

    public static class Names { 
     public Names() {} 

     @XmlElement(name = "name") 
     @Field("title") 
     public List<Name> name; 

     public static class Name { 
      public Name() {} 

      @XmlValue 
      public String value; 
     } 
    } 

    @XmlElement(name = "names") 
    public Names names; 

} 

兩個單元測試,我已經制作:

public class CompanySearchTest extends AbstractSolrTestCase { 

    private SolrServer server; 

    private Company company; 

    @Before 
    @Override 
    public void setUp() throws Exception { 
     super.setUp(); 
     server = new EmbeddedSolrServer(h.getCoreContainer(), h.getCore().getName()); 

     company = new Company(); 
     company.registryNumber = "5226805000"; 
     Company.Names.Name name1 = new Company.Names.Name(); 
     name1.value = "name1"; 
     Company.Names.Name name2 = new Company.Names.Name(); 
     name1.value = "name2"; 
     Company.Names names = new Company.Names(); 
     names.name = Arrays.asList(name1, name2); 

     server.addBean(company); 
     server.commit(); 
    } 

    @After 
    public void destroy() { 
     h.getCoreContainer().shutdown(); 
    } 

    @Test 
    public void searchByIdTest() throws IOException, SolrServerException { 
     SolrQuery query = new SolrQuery(); 
     query.setQuery("id:5226805000"); 

     QueryResponse response = server.query(query); 

     List<Company> companiesFound = response.getBeans(Company.class); 

     assertEquals(1L, companiesFound.size()); 
     assertEquals("5226805000", companiesFound.get(0).registryNumber);  
    } 

    @Test 
    public void searchByMultivalueNameTest() throws IOException, SolrServerException { 
     SolrQuery query = new SolrQuery(); 
     query.setQuery("title:name1"); 

     QueryResponse response = server.query(query); 

     List<Company> companiesFound = response.getBeans(Company.class); 

     assertEquals(1L, companiesFound.size()); 
     assertEquals("name1", companiesFound.get(0).names.name.get(0).value); 
    } 

    @Override 
    public String getSchemaFile() { 
     return "solr/collection1/conf/schema.xml"; 
    } 

    @Override 
    public String getSolrConfigFile() { 
     return "solr/collection1/conf/solrconfig.xml"; 
    } 
} 

測試searchByIdTest()通過,而searchByMultivalueNameTest()失敗,因爲沒有公式紐約州是通過搜索發現:

query.setQuery("title:name1"); 

我使用Solr模式是提供使用Solr 4.0.0(收集1例)。

有人可以給我一些提示如何,如果可能的話,應該我註釋公司POJO或者我應該做什麼修改。

的目標是有<name>name1</name><name>name2</name>索引爲多值Solr的字符串字段作爲例子Solr模式,並定義了:

<field name="title" type="text_general" indexed="true" stored="true" multiValued="true"/> 

因此該公司可以通過搜索找到「標題:名稱1」或者「標題:NAME2" 。

非常感謝!

回答

1

正如佩奇指出:

SolrJ不支持複雜類型多值字段

我修改了公司的POJO(我喜歡刪除自己的代碼行!):

@XmlRootElement(name = "company") 
public class Company { 
    public Company() {} 

    @XmlElement 
    @Field("id") 
    public String registryNumber; 

    @XmlElementWrapper(name = "names") 
    @XmlElement(name = "name") 
    @Field("title") 
    public List<String> names; 
} 

當然,XML保持不變。

的單元測試設置()方法也被簡化了:

@Before 
@Override 
public void setUp() throws Exception { 
    super.setUp(); 
    server = new EmbeddedSolrServer(h.getCoreContainer(), h.getCore().getName()); 

    company = new Company(); 
    company.registryNumber = "5226805000"; 
    company.names= Arrays.asList("name1", "name2"); 

    server.addBean(company); 
    server.commit(); 
} 

的斷言也簡化了,但我增加了兩個查詢,以確認正確的搜索正在發生的事情:

@Test 
    public void searchByMultivalueNameTest() throws IOException, SolrServerException { 
     SolrQuery query = new SolrQuery(); 
     query.setQuery("title:name1"); 

     QueryResponse response = server.query(query); 

     List<Company> companiesFound = response.getBeans(Company.class); 

     assertEquals(1L, companiesFound.size()); 
     assertEquals("name1", companiesFound.get(0).names.get(0)); 

     // 2nd query 
     query.clear(); 
     query.setQuery("title:name2"); 

     response = server.query(query); 

     companiesFound = response.getBeans(Company.class); 

     assertEquals(1L, companiesFound.size()); 
     assertEquals("name2", companiesFound.get(0).names.get(1)); 

     // 3rd query 
     query.clear(); 
     query.setQuery("title:name1 AND title:name2"); 

     response = server.query(query); 

     companiesFound = response.getBeans(Company.class); 

     assertEquals(1L, companiesFound.size()); 
     assertEquals("name1", companiesFound.get(0).names.get(0)); 
     assertEquals("name2", companiesFound.get(0).names.get(1));  

    } 

這就是它。我希望別人覺得這很有用。