SDN4或neo4j-ogm表演问题

时间:2015-10-01 10:14:17

标签: neo4j spring-data-neo4j-4 neo4j-ogm

我写了一些简单的java代码,我遇到了SDN4的一些糟糕表现,我没有用SDN3。我怀疑查找存储库方法深度参数不能完全按照它应该的方式工作。让我解释一下这个问题:

这是我的java类(它只是一个例子),我在其中删除了getter,setter,contructors,......

头等舱是'元素' :

@NodeEntity
public class Element {

@GraphId
private Long id;

private int age;

private String  uuid;

@Relationship(type = "HAS_VALUE", direction = Relationship.OUTGOING)
private Set<Value> values = new HashSet<Value>();

第二个是&#39;属性&#39;

@NodeEntity
public class Attribute {
@GraphId
private Long id;

@Relationship(type = "HAS_PROPERTIES", direction = Relationship.OUTGOING)
private Set<HasInterProperties> properties;

&#39;价值&#39; class允许我的用户在Element上为特定属性添加值:

@RelationshipEntity(type = "HAS_VALUE")
public class Value {

@GraphId
private Long id;

@StartNode
Element element;

@EndNode
Attribute attribute;

private Integer value;

private String uuid;

public Value() {
}

public Value(Element element, Attribute attribute, Integer value) {
    this.element = element;
    this.attribute = attribute;
    this.value = value;
    this.element.getValues().add(this);
    this.uuid = UUID.randomUUID().toString();
}

&#39;元素&#39; classe真的需要知道它的价值,但是&#39;属性&#39;上课并不关心价值观。

属性具有对InternationalizedProperties类的引用,如下所示:

@NodeEntity
public class InternationalizedProperties {
@GraphId
private Long id;

private String name;

属性与InternationalizedProperties之间的关系实体如下所示:

@RelationshipEntity(type = "HAS_PROPERTIES")
public class HasInterProperties {

@GraphId
private Long id;

@StartNode
private Attribute attribute;

@EndNode
private InternationalizedProperties properties;

private String locale;

然后我创建了一个主要的方法来创建两个属性和10000个元素。我的所有元素都有第一个属性的特定值,但没有第二个属性的值(它们之间没有关系)。这两个属性都有两个不同的国际化属性。这是一个示例:

public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring/*.xml");
     Session session = context.getBean(Session.class);
    session.query("START n=node(*) OPTIONAL MATCH n-[r]-() WHERE ID(n) <> 0 DELETE n,r", new HashMap<String, Object>());
    ElementRepository elementRepository = context.getBean(ElementRepository.class);
    AttributeRepository attributeRepository = context.getBean(AttributeRepository.class);
    InternationalizedPropertiesRepository internationalizedPropertiesRepository = context.getBean(InternationalizedPropertiesRepository.class);
    HasInterPropertiesRepository hasInterPropertiesRepository = context.getBean(HasInterPropertiesRepository.class);

    //Creation of an attribute object with two internationalized properties
    Attribute att = new Attribute();
    attributeRepository.save(att);
    InternationalizedProperties p1 = new InternationalizedProperties();
    p1.setName("bonjour");
    internationalizedPropertiesRepository.save(p1);
    InternationalizedProperties p2 = new InternationalizedProperties();
    p2.setName("hello");
    internationalizedPropertiesRepository.save(p2);
    hasInterPropertiesRepository.save(new HasInterProperties(att, p1, "fr"));
    hasInterPropertiesRepository.save(new HasInterProperties(att, p2, "en"));
    LOGGER.info("First attribut id is {}", att.getId());

    //Creation of 1000 elements having a differnt value on a same attribute

    for(int i = 0; i< 10000; i++) {
        Element elt = new Element();
        new Value(elt, att, i);
        elementRepository.save(elt);
        if(i%50 == 0) {
            LOGGER.info("{} elements created. Last element created with id {}", i+1, elt.getId());
        }
    }

    //Another attribut without any values from element.
    Attribute att2 = new Attribute();
    attributeRepository.save(att2);
    InternationalizedProperties p12 = new InternationalizedProperties();
    p12.setName("bonjour");
    internationalizedPropertiesRepository.save(p12);
    InternationalizedProperties p22 = new InternationalizedProperties();
    p22.setName("hello");
    internationalizedPropertiesRepository.save(p22);
    hasInterPropertiesRepository.save(new HasInterProperties(att2, p12, "fr"));
    hasInterPropertiesRepository.save(new HasInterProperties(att2, p22, "en"));
    LOGGER.info("Second attribut id is {}", att2.getId());

最后,在另一个主要方法中,我尝试多次获得第一个属性和第二个属性:

private static void getFirstAttribute(AttributeRepository attributeRepository) {
    StopWatch st = new StopWatch();
    st.start();
    Attribute attribute = attributeRepository.findOne(25283L, 1);
    LOGGER.info("time to get attribute (some element have values on it) is {}ms", st.getTime());
}

private static void getSecondAttribute(AttributeRepository attributeRepository) {
    StopWatch st = new StopWatch();
    st.start();
    Attribute attribute2 = attributeRepository.findOne(26286L, 1);
    LOGGER.info("time to get attribute (no element have values on it) is {}ms", st.getTime());
}

public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring/*.xml");

    AttributeRepository attributeRepository = context.getBean(AttributeRepository.class);

    getFirstAttribute(attributeRepository);
    getSecondAttribute(attributeRepository);

    getFirstAttribute(attributeRepository);
    getSecondAttribute(attributeRepository);

    getFirstAttribute(attributeRepository);
    getSecondAttribute(attributeRepository);

    getFirstAttribute(attributeRepository);
    getSecondAttribute(attributeRepository);
}

以下是此执行的日志:

time to get attribute (some element have values on it) is 2983ms
time to get attribute (no element have values on it) is 4ms     
time to get attribute (some element have values on it) is 1196ms
time to get attribute (no element have values on it) is 2ms     
time to get attribute (some element have values on it) is 1192ms
time to get attribute (no element have values on it) is 3ms     
time to get attribute (some element have values on it) is 1194ms
time to get attribute (no element have values on it) is 3ms     

获得第二个属性(以及它的国际化属性,由于深度= 1)非常快,但要获得第一个仍然非常慢。我知道有很多关系(确切地说10000个)指向第一个属性,但是当我想获得具有国际化属性的属性时,我显然不希望获得指向它的所有值。 (因为未在Attribute类上指定Set)。

这就是为什么我认为这里存在性能问题。或者我可能做错了什么?

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

从图表加载数据时,我们目前尚未分析您的域模型如何连接在一起,因此我们可能会带回您不需要的相关节点。如果它们在您的域中不可映射,则会被丢弃,但如果它们中有很多,则可能会影响响应时间。

这种方法有两个原因。

  • 对任何深度创建通用查询显然要简单得多,而不是将您的域模型动态分析到任意深度并生成即时自定义查询;它也更容易分析和证明通用查询的正确性。

  • 我们希望保留支持多态域的功能 未来的模型,我们不必知道其中的内容 数据库从一天到下一天,但我们想要调整我们的域名 根据我们发现的模型水合作用。

在这种情况下,我建议编写一个自定义查询来加载属性对象,以确保不会带回所有不需要的关系。

相关问题