Ed,
Sorry for the late reply, I needed to get my head around this properly.
So, there are actually a couple of issues here:
1) You cannot shoehorn two fields into the same fieldname on the same index
2) Collections are indexed by their toString value
That said, here is some code that illustrates the problem and works around it. For your case, consider creating a special field with both name and aliases in it. On the one hand, that violates modelling purity. But on the other hand, these entities are really DTOs with the special purpose of facilitating database querying. So I think it is acceptable.
Notice the aliasesAsCollection-field, it is a Lucene full-text index on a space-delimited string representation of the list of aliases. If you need stricter matching you would probably have to add quotes in places.
Code:
interface PersonRepository extends GraphRepository<Person>, NamedIndexRepository<Person> {
}
@NodeEntity
class Person {
@GraphId
Long id;
@Indexed
String name;
@Indexed
String[] aliasesAsArray;
@Indexed(indexName = "extra_index", indexType = IndexType.FULLTEXT)
Set<String> aliasesAsCollection;
Person() {
}
Person(String name, final Set<String> aliases) {
this.name = name;
aliasesAsArray = aliases.toArray(new String[aliases.size()]);
aliasesAsCollection = new HashSet<String>(aliases) {
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
for (String alias : aliases) {
stringBuilder.append(alias);
stringBuilder.append(" ");
}
return stringBuilder.toString();
}
};
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@Transactional
public class IndexTests {
@Configuration
@EnableNeo4jRepositories
static class TestConfig extends Neo4jConfiguration {
@Bean
GraphDatabaseService graphDatabaseService() {
return new ImpermanentGraphDatabase();
}
}
@Autowired
Neo4jTemplate template;
@Autowired
GraphDatabaseService graphDatabaseService;
@Autowired
PersonRepository personRepository;
@Before
public void before() {
personRepository.save(new Person("Shawn Corey Carter", new HashSet<String>(asList("Jay-Z"))));
personRepository.save(new Person("Sean Coombs", new HashSet<String>(asList("P-diddy", "Puff Daddy"))));
personRepository.save(new Person("Curtis James Jackson", new HashSet<String>(asList("50 Cent"))));
}
@Test
public void shouldFindByMemberOfIndexedArray() throws Exception {
assertThat(personRepository.findAllByQuery("aliasesAsArray", "P-diddy").single().name, is(equalTo("Sean Coombs")));
assertThat(personRepository.findAllByQuery("aliasesAsArray", "\"Puff Daddy\"").single().name, is(equalTo("Sean Coombs")));
}
@Test
public void shouldFindByMemberOfIndexedCollection() throws Exception {
assertThat(personRepository.findAllByQuery("extra_index", "aliasesAsCollection", "P-diddy").single().name, is(equalTo("Sean Coombs")));
assertThat(personRepository.findAllByQuery("extra_index", "aliasesAsCollection", "Puff Daddy").single().name, is(equalTo("Sean Coombs")));
assertThat(personRepository.findAllByQuery("extra_index", "aliasesAsCollection", "Puff").single().name, is(equalTo("Sean Coombs")));
assertThat(personRepository.findAllByQuery("extra_index", "aliasesAsCollection", "Daddy").single().name, is(equalTo("Sean Coombs")));
}
}
Hope that helps. I'll raise a jira for the collection indexing problem.
Regards,
Lasse