1

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

我对编组没有问题 - Company 对象构建得很好。我遇到的问题是如何注释 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 示例)。

有人可以给我一些提示,如果可能的话,我应该如何注释 Company 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”找到该公司。

非常感谢!

4

2 回答 2

1

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

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

    @XmlElement(name = "name")
    @Field("title")
    public List<String> name;
于 2012-12-18T13:17:26.587 回答
1

正如佩奇指出的那样:

SolrJ 不支持多值字段的复杂类型

我已经修改了 Company 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));      

    }

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

于 2012-12-19T09:06:42.877 回答