将POJO与带有JAXB和Solr注释的嵌套类一起使用

时间:2012-12-18 10:19:41

标签: java solr jaxb annotations

我希望尽可能少的类,所以我想构建一个JAXB和Solr注释的POJO ,正如您可能猜到的那样,使用XML,将其编组到Company对象中,索引它。

我对编组没有任何问题 - 公司对象构造得很好。我遇到的问题是如何注释公司POJO以创建多值字符串solr字段

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"/>

所以可以通过搜索“title:name1”或“title:name2”找到公司。

非常感谢!

2 个答案:

答案 0 :(得分:1)

问题在于SolrJ不支持多值字段的复杂类型。请参阅上一个问题 - solrj: how to store and retrieve List via multivalued field in index

您需要将字段定义更改为以下内容:

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

答案 1 :(得分:1)

Paige指出:

  

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当然保持不变。

单元测试setUp()方法也简化了:

@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));      

    }

就是这样。我希望其他人觉得这很有用。