没有结果使用Spring Data Neo4j存储库查询Neo4j数据库

时间:2015-09-23 02:30:57

标签: java mysql spring neo4j

由于在另一个Neo4j数据库中转换MySQL数据库,我创建了一个图形数据库作为分层树。转型运作良好。

在顶层存在标记为Root的节点,在第二级存在标记为Country的国家/地区。每个国家都有标有城市的第三级城市。每个城市都有一个标记为地址的地址子集。关系应该是,

(root)-[:IS_ROOT]->(country)-[:HAS_CITY]->(city)-[:HAS_ADDRESS]->(address)

后来,使用Spring Data Neo4j存储库,我试图查询没有结果的数据库。

对于MySQL数据库,我使用JDBC,对于Neo4j数据库,我使用前面提到的Spring Data Neo4j。

这是我用来创建Neo4j数据库的控制器,

@Controller("importer")
public class SakilaDbImportController {

private static final Logger logger = LoggerFactory.getLogger(SakilaDbImportController.class);

@Autowired
@Lazy
AddressNeoRepository addressRepo;

@Autowired
@Lazy
CityNeoRepository cityRepo;

@Autowired
@Lazy
CountryNeoRepository countryRepo;

@Autowired
@Lazy
RootRepository rootRepo;

@Autowired
Neo4jTemplate template;

@Autowired
SakilaDbApiClient client;

public SakilaDbImportController() {

}

@Transactional
public RootNeo createGraphDb() {
    RootNeo root = doImportRoot();
    return root;
}

@Transactional
public RootNeo importRoot() {
    return doImportRoot();
}

private RootNeo doImportRoot() {
    logger.debug("Importing root");

    RootNeo root = new RootNeo("1", "Root");
    root.addLabel("_Root");
    //root.addLabel("Root");
    System.out.println("root created " + root);

    List<Country> data = client.readAllCountries();
    if (data.isEmpty()) throw new RuntimeException("Data for Root not found.");

    Map<CountryNeo, RoleIsRoot> roles = relateCountriesToRoot(root, data);
    //template.save(root);
    Set<CountryNeo> set = roles.keySet();
    for(Iterator<CountryNeo> it = set.iterator(); it.hasNext();) {
        root.isRoot(it.next());
    }
    rootRepo.save(root);

    /*
    for(RoleIsRoot role: roles){
        template.save(role);
    }
    */

    return root;
}

private Map<CountryNeo, RoleIsRoot> relateCountriesToRoot(RootNeo root, List<Country> data) {
    Map<CountryNeo, RoleIsRoot> roles = new HashMap<CountryNeo, RoleIsRoot>();
    for (Country country : data) {
        if(country.getCountry().equalsIgnoreCase("Canada"))
            continue;
        CountryNeo countryNeo = doImportCountryNeo(country);
        RoleIsRoot role = root.isRoot(countryNeo, "IS_ROOT_OF");
        System.out.println("RoleIsRoot: " + role);
        roles.put(countryNeo, role);
    }

    return roles;
}

@Transactional
public CountryNeo importCountryNeo(Country country) {
    return doImportCountryNeo(country);
}

private CountryNeo doImportCountryNeo(Country country) {
    logger.debug("Importing countryNeo");

    CountryNeo countryNeo = new CountryNeo(generateIndex(country.getCountryId()), country.getCountry());
    countryNeo.addLabel("_Country");
    //countryNeo.addLabel("Country");
    System.out.println("new country: " + countryNeo);

    List<City> data = client.readAllCitiesByCountry(country);
    if (data.isEmpty()) throw new RuntimeException("Data for Country not found.");

    Map<CityNeo, RoleHasCity> roles = relateCitiesToCountry(countryNeo, data);
    Set<CityNeo> set = roles.keySet();
    for(Iterator<CityNeo> it = set.iterator(); it.hasNext();) {
        countryNeo.hasCity(it.next());
    }
    countryRepo.save(countryNeo);

    /*
    template.save(countryNeo);
    for(RoleHasCity role: roles){
        template.save(role);
    }
    */

    return countryNeo;
}

private Map<CityNeo, RoleHasCity> relateCitiesToCountry(CountryNeo countryNeo, List<City> data) {
    Map<CityNeo, RoleHasCity> roles = new HashMap<CityNeo, RoleHasCity>();
    for (City city : data) {
        CityNeo cityNeo = doImportCityNeo(city);
        RoleHasCity role = countryNeo.hasCity(cityNeo, "IS_CITY_FROM");
        System.out.println("RoleHasCity: " + role);
        roles.put(cityNeo, role);
    }

    return roles;
}

@Transactional
public CityNeo importCityNeo(City city) {
    return doImportCityNeo(city);
}

private CityNeo doImportCityNeo(City city) {
    logger.debug("Importing cityNeo");

    CityNeo cityNeo = new CityNeo(generateIndex(city.getCityId()), city.getCity());
    cityNeo.addLabel("_City");
    //cityNeo.addLabel("City");
    System.out.println("new city: " + cityNeo);

    List<Address> data = client.readAllAddressesByCity(city);
    if (data.isEmpty()) throw new RuntimeException("Data for City not found.");

    Map<AddressNeo, RoleHasAddress> roles = relateAddressesToCity(cityNeo, data);
    Set<AddressNeo> set = roles.keySet();
    for(Iterator<AddressNeo> it = set.iterator(); it.hasNext();) {
        cityNeo.hasAddress(it.next());
    }
    cityRepo.save(cityNeo);

    /*
    template.save(cityNeo);
    for(RoleHasAddress role: roles){
        template.save(role);
    }
    */

    return cityNeo;
}

private Map<AddressNeo, RoleHasAddress> relateAddressesToCity(CityNeo cityNeo, List<Address> data) {
    Map<AddressNeo, RoleHasAddress> roles = new HashMap<AddressNeo, RoleHasAddress>();
    for(Address address: data) {
        AddressNeo addressNeo = doImportAddressNeo(address);
        RoleHasAddress role = cityNeo.hasAddress(addressNeo, "IS_ADDRESS_IN");
        System.out.println("RoleHasAddress: " + role);
        roles.put(addressNeo, role);
    }

    return roles;
}

@Transactional
public AddressNeo importAddressNeo(Address address) {
    return doImportAddressNeo(address);
}

private AddressNeo doImportAddressNeo(Address address) {
    logger.debug("Importing addressNeo");

    if (address == null) throw new RuntimeException("Address not found.");

    AddressNeo addressNeo = new AddressNeo(generateIndex(address.getAddressId()), address.getAddress());
    addressNeo.addLabel("_Address");
    //addressNeo.addLabel("Address");
    System.out.println("new address: " + addressNeo);

    addressNeo.setPostalCode(address.getPostalCode());
    addressRepo.save(addressNeo);

    /*
    template.save(addressNeo);
    */

    return addressNeo;
}

private String generateIndex(int index) {
    return String.valueOf(index);
}
}

这是使用存储库执行查询的服务

@Service
public class SakilaDbQueries {

@Autowired
@Lazy
AddressNeoRepository addressRepo;

@Autowired
@Lazy
CityNeoRepository cityRepo;

@Autowired
@Lazy
CountryNeoRepository countryRepo;

@Autowired
@Lazy
RootRepository rootRepo;

public SakilaDbQueries() {

}

public List<String> findAllCountryNames() {
    CountryNeoData names = countryRepo.findAllCountryNames();
    Collection<String> collection = names.getCountries();

    List<String> list = new ArrayList<String>();
    for(Iterator<String> it = collection.iterator(); it.hasNext(); ) {
        list.add(it.next());
    }

    return list;
}

public List<CountryNeo> findAllCountries() {
    Result<CountryNeo> result = countryRepo.findAll();

    List<CountryNeo> list = new ArrayList<CountryNeo>();
    for(Iterator<CountryNeo> it = result.iterator(); it.hasNext(); ) {
        list.add(it.next());
    }

    return list;
}
}

作为一个例子,

这是NodeEntity Place作为通用的

@NodeEntity
public class Place {

@GraphId Long nodeId;

@Indexed(unique=true)
String id;

@Indexed(indexType=IndexType.FULLTEXT, indexName = "place")
String name;

@Labels 
private Collection<String> labels = Collections.emptySet(); 


protected Place(String id, String name) {
    this.id = id;
    this.name = name;
}

protected Place() {
}

public String getId() {
    return id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public void addLabel(String label) {
    HashSet<String> newLabels = new HashSet<>(this.labels);
    if (newLabels.add(label)) this.labels = newLabels;
}

public void removeLabel(String label) {
    HashSet<String> newLabels = new HashSet<>(this.labels);
    if (newLabels.remove(label)) this.labels = newLabels;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Place place = (Place) o;
    if (nodeId == null) return super.equals(o);
    return nodeId.equals(place.nodeId);

}

@Override
public int hashCode() {
    return nodeId != null ? nodeId.hashCode() : super.hashCode();
}

@Override
public String toString() {
    return String.format("%s [%s]", name, id);
}

}

和CountryNeo扩展了Place,

@NodeEntity
public class CountryNeo extends Place {

@RelatedTo(type = "HAS_CITY", direction = Direction.OUTGOING)
Set<CityNeo> cities;

@Fetch @RelatedToVia(type = "IS_ROOT", direction = Direction.INCOMING)
Iterable<RoleIsRoot> roles;

public CountryNeo() {
}

public CountryNeo(String id, String name) {
    super(id, name);
}

public Set<CityNeo> getCities() {
    return cities;
}

public void hasCity(CityNeo city) {
    if(cities == null)
        cities = new HashSet<CityNeo>();
    cities.add(city);
}

public RoleHasCity hasCity(CityNeo city, String roleName) {
    return new RoleHasCity(this, city, roleName);
}

public Collection<RoleIsRoot> getRoles() {
    Iterable<RoleIsRoot> allRoles = roles;
    return allRoles == null ? Collections.<RoleIsRoot>emptyList() : IteratorUtil.asCollection(allRoles);
}
}

使用过的角色,

@RelationshipEntity(type = "HAS_CITY")
public class RoleHasCity {
@GraphId Long id;

@StartNode CountryNeo country;
@EndNode CityNeo city;

String name;

public RoleHasCity() {

}

public RoleHasCity(CountryNeo country, CityNeo city, String roleName) {
    this.country = country;
    this.city = city;
    this.name = roleName;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public CountryNeo getCountry() {
    return country;
}

public void setCountry(CountryNeo country) {
    this.country = country;
}

public CityNeo getCity() {
    return city;
}

public void setCity(CityNeo city) {
    this.city = city;
}

@Override
public String toString() {
    return String.format("%s %s %s", city, name, country);
}
}

和存储库,

public interface CountryNeoRepository extends GraphRepository<CountryNeo> {

@Query("MATCH (n:CountryNeo) RETURN COLLECT(n.name) AS countries")
CountryNeoData findAllCountryNames();

@QueryResult
public class CountryNeoData {
    Collection<String> countries = Collections.emptyList();

    public Collection<String> getCountries() {
        return countries;
    }
}
}

这是主要的bean,

public class SakilaImporter {

private GraphDatabaseService graphDatabase;
private SakilaDbImportController importer;
private SakilaDbQueries queries;

public SakilaImporter(GraphDatabaseService graphDatabase,
        SakilaDbImportController importer,
        SakilaDbQueries queries) {
    this.graphDatabase = graphDatabase;
    this.importer = importer;
    this.queries = queries;
}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

    GraphDatabaseService graphDatabase = ctx.getBean("graphDatabaseService", GraphDatabaseService.class);
    SakilaDbImportController importer = ctx.getBean("importer", SakilaDbImportController.class);
    SakilaDbQueries queries = ctx.getBean("queries", SakilaDbQueries.class);

    SakilaImporter sakilaImporter = new SakilaImporter(graphDatabase, importer, queries);

    Transaction tx = graphDatabase.beginTx();
    try {
        sakilaImporter.createDatabase();
        sakilaImporter.queryDatabase();
        tx.success();
    } finally {
        tx.close();
    }
    ctx.close();
}

public void createDatabase() {
    System.out.println("Importing data...");
    final long start = System.currentTimeMillis();
    RootNeo root = importer.createGraphDb();
    if(root != null) {
        final long time = System.currentTimeMillis() - start;
        System.out.println("Import places took " + time + " ms.");
    } else {
        System.out.println("root: " + root);
    }    
}

public void queryDatabase() {
    System.out.println();System.out.println();
    System.out.println("List of countries.-");
    List<CountryNeo> countries = queries.findAllCountries();
    for(CountryNeo country: countries) {
        System.out.println(country);
    }
    System.out.println();System.out.println();
    System.out.println("List of country names.-");
    List<String> names = queries.findAllCountryNames();
    for(String name: names) {
        System.out.println(name);
    }
}
}

两个查询的结果都是一个空列表

  • spring 2.5.6
  • spring framework 4.0.0.RELEASE
  • neo4j 2.1.8
  • spring data neo4j 3.1.2.RELEASE

0 个答案:

没有答案