我希望尽可能少的类,所以我想构建一个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”找到公司。
非常感谢!
答案 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));
}
就是这样。我希望其他人觉得这很有用。