【问题标题】:Neo4j OGM Neo4jSession variable substitution queries failNeo4j OGM Neo4jSession 变量替换查询失败
【发布时间】:2016-06-14 23:07:27
【问题描述】:

对我来说:

neo4jSession.query("MATCH (n:Widget) WHERE (n.partNumber STARTS WITH '001') RETURN n.partNumber AS id, n.name AS description, n.urn AS urn LIMIT 10", Collections.emptyMap());

有效。

此查询不起作用:

    String query = "MATCH (n:Widget) " +
    "WHERE (n.partNumber STARTS WITH {queryString}) " +
    "RETURN n.partNumber AS id, n.name AS description, n.urn AS urn " +
    "LIMIT {limit}";
Map<String, Object> params = ImmutableMap
    .<String, Object>builder()
    .put("queryString", queryString)
    .put("limit", limit)
    .build();
return (List) neo4jOperations.queryForObjects(Object.class, query, params);

它返回一个空列表。我也尝试过使用我的实际域对象:

 return (List) neo4jOperations.queryForObjects(Widget.class, query, params);

结果相同。

我正在使用 OGM 2.0.2、neo4j 2.3.2 和 Spring Data Neo4j 4.1.1,但我已经尝试过没有使用 Neo4jSession 的 Neo4jOperations,结果相同。哦,我也在使用带有 HTTP 驱动程序的 neo4j 的删除实例。

OGM 有问题吗?

更多信息:

通过网络,我相信消息如下所示:

{      "statements":[  
      {  
         "statement":"MATCH (n:Widget) WHERE (n.partNumber STARTS WITH {queryString}) RETURN n.partNumber AS id, n.name AS description, n.urn AS urn LIMIT {limit}",
         "parameters":{  
            "queryString":"001",
            "limit":10
         },
         "resultDataContents":[  
            "graph"
         ],
         "includeStats":false
      }    ] }




{      "statements":[  
      {  
         "statement":"MATCH (n:Widget) WHERE (n.partNumber STARTS WITH '001') RETURN n.partNumber AS id, n.name AS description, n.urn AS urn LIMIT 10",
         "parameters":{  

         },
         "resultDataContents":[  
            "rest"
         ],
         "includeStats":true
      }    ] }

更多信息:

我已经尝试将 Widget 用作 @QueryResult 和 @NodeEntity(带有 getter 和 setter)。

@QueryResult
public class TypeaheadData {
  public Object id;
  public String description;
  public String uid;
}

@NodeEntity
public class TypeaheadData {
  public Object id;
  public String description;
  public String uid;

  public TypeaheadData() {
  }

  public Object getId() {
    return id;
  }

  public void setId(Object id) {
    this.id = id;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public String getUid() {
    return uid;
  }

  public void setUid(String uid) {
    this.uid = uid;
  }
}

我还检查了网络上的响应,在这两种情况下,它看起来都是这样的:

{  
   "results":[  
      {  
         "columns":[  
            "id",
            "description",
            "uid"
         ],
         "data":[  
            {  
               "graph":{  
                  "nodes":[  

                  ],
                  "relationships":[  

                  ]
               }
            },
            {  
               "graph":{  
                  "nodes":[  

                  ],
                  "relationships":[  

                  ]
               }
            },
            {  
               "graph":{  
                  "nodes":[  

                  ],
                  "relationships":[  

                  ]
               }
            },
            {  
               "graph":{  
                  "nodes":[  

                  ],
                  "relationships":[  

                  ]
               }
            },
            {  
               "graph":{  
                  "nodes":[  

                  ],
                  "relationships":[  

                  ]
               }
            },
            {  
               "graph":{  
                  "nodes":[  

                  ],
                  "relationships":[  

                  ]
               }
            },
            {  
               "graph":{  
                  "nodes":[  

                  ],
                  "relationships":[  

                  ]
               }
            },
            {  
               "graph":{  
                  "nodes":[  

                  ],
                  "relationships":[  

                  ]
               }
            },
            {  
               "graph":{  
                  "nodes":[  

                  ],
                  "relationships":[  

                  ]
               }
            },
            {  
               "graph":{  
                  "nodes":[  

                  ],
                  "relationships":[  

                  ]
               }
            }
         ]
      }
   ],
   "errors":[  

   ]
}

如果我删除了 Widget @NodeEntity,这是发出的请求:

{  
   "statements":[  
      {  
         "statement":"MATCH (n:Widget) WHERE (n.partNumber STARTS WITH {queryString}) RETURN n.partNumber AS id, n.name AS description, n.urn AS urn LIMIT {limit}",
         "parameters":{  
            "queryString":"001",
            "limit":10
         },
         "resultDataContents":[  
            "row"
         ],
         "includeStats":false
      }
   ]
}

并且删除了小部件@NodeEntity,响应中确实包含正确的数据,但映射器抛出:

标量响应查询只能返回一列。确保您的 密码查询只返回一项。

【问题讨论】:

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


    【解决方案1】:

    OGM 无法将属性集合映射到域实体。 您的查询返回:

    RETURN n.partNumber AS id, n.name AS description, n.urn AS urn 
    

    但是没有什么可以告诉 OGM 这是一个什么样的实体,如果它是一个实体的话。

    将其更改为 RETURN n 应该与 neo4jOperations.queryForObjects(Widget.class, query, params); 一起工作

    【讨论】:

    【解决方案2】:

    Neo4j OGM 无法处理不返回整个节点对象的映射查询。如果您在查询中仅请求节点属性的子集,则必须使用返回结果的查询方法。然后你必须自己做映射。

    如果您使用的是 spring-data-neo4j,那么您可以使用他们的 @QueryResult 注释与存储库 @Query 混合来为您处理映射。如果你看一下代码,他们已经从 Neo4jSession 提供的元数据中找到了一个映射器。

    一个例外是,如果您在节点上查询单个属性,那么 queryForObjects 函数将起作用。

    对我来说似乎是一个疏忽,但我该说谁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      相关资源
      最近更新 更多