一个 AQL 查询中的多个 INSERT:数据修改错误后访问
Multiple INSERTs in One AQL Query: Access After Data-Modification Error
系统设置
- ArangoDB: v3.4.7
- Java驱动程序:v5.0.0
问题
我正在尝试在 ArangoDB 的单个查询中执行多个插入。具体如下:
INSERT { _key: @personId, firstName: @firstName, lastName: @lastName, gender: @gender, birthday: @birthday, birthday_day: @birthday_day, birthday_month: @birthday_month, creationDate: @creationDate, locationIP: @locationIP, browserUsed: @browserUsed, email:
@email, speaks: @speaks } INTO Person
INSERT { _from: Person/@personId, _to: Place/@placeId } INTO isLocatedIn
INSERT { _from: Person/@personId, _to: Tag/@tag0Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag1Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag2Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag3Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag4Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag5Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag6Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag7Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag8Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag9Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag10Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag11Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag12Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag13Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag14Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag15Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag16Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag17Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag18Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag19Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag20Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag21Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Organisation/@studyOrg0Id, classYear: @classYear0 } INTO studyAt
INSERT { _from: Person/@personId, _to: Organisation/@workOrg0Id, classYear: @workFrom0 } INTO workAt
INSERT { _from: Person/@personId, _to: Organisation/@workOrg1Id, classYear: @workFrom1 } INTO workAt
使用以下参数:
Params: {personId=35184372096260, firstName=André, lastName=Atem, gender=female, birthday=501897600000, birthday_day=27, birthday_month=11, creationDate=1347546700674, locationIP=41.205.16.11, browserUsed=Internet Explorer, email=[Andre35184372096260@yahoo.com], speaks=
[en], placeId=1048, tag0Id=285, tag1Id=441, tag2Id=1761, tag3Id=2019, tag4Id=2800, tag5Id=2832, tag6Id=4994, tag7Id=5116, tag8Id=5446, tag9Id=5531, tag10Id=5677, tag11Id=6369, tag12Id=7340, tag13Id=7756, tag14Id=7853, tag15Id=8219, tag16Id=8481, tag17Id=9738, tag18Id=98
68, tag19Id=10410, tag20Id=11121, tag21Id=11211, studyOrg0Id=1980, classYear0=2004, workOrg0Id=205, workFrom0=2006, workOrg1Id=209, workFrom1=2005}
但是当我尝试这样做时,出现以下错误:
Exception in thread "main" com.arangodb.ArangoDBException: Response: 400, Error: 1579 - AQL: access after data-modification by collection 'Person' (while optimizing ast)
at com.arangodb.internal.util.ResponseUtils.checkError(ResponseUtils.java:53)
at com.arangodb.internal.velocystream.VstCommunication.checkError(VstCommunication.java:146)
at com.arangodb.internal.velocystream.VstCommunicationSync.execute(VstCommunicationSync.java:128)
at com.arangodb.internal.velocystream.VstCommunicationSync.execute(VstCommunicationSync.java:42)
at com.arangodb.internal.velocystream.VstCommunication.execute(VstCommunication.java:129)
at com.arangodb.internal.velocystream.VstProtocol.execute(VstProtocol.java:47)
at com.arangodb.internal.ArangoExecutorSync.execute(ArangoExecutorSync.java:71)
at com.arangodb.internal.ArangoExecutorSync.execute(ArangoExecutorSync.java:53)
at com.arangodb.internal.ArangoDatabaseImpl.query(ArangoDatabaseImpl.java:197)
似乎在 ArangoDB 中我不能在一个查询中向同一个集合插入两次?我是否需要为每个 INSERTS 执行单独的查询?
感谢您的帮助!
解决方案
使用 FOR
结构重新表述 AQL 查询解决了问题:
INSERT { _key: @personId, firstName: @firstName, lastName: @lastName, gender: @gender, birthday: @birthday, birthday_day: @birthday_day, birthday_month: @birthday_month, creationDate: @creationDate, locationIP: @locationIP, browserUsed: @browserUsed, email: @email, speaks: @speaks } INTO Person
LET hasInterestEdges = [
{_from: "Person/35184372096260", _to: "Tag/285"},
{_from: "Person/35184372096260", _to: "Tag/441"},
{_from: "Person/35184372096260", _to: "Tag/1761"},
{_from: "Person/35184372096260", _to: "Tag/2019"},
{_from: "Person/35184372096260", _to: "Tag/2800"},
{_from: "Person/35184372096260", _to: "Tag/2832"},
{_from: "Person/35184372096260", _to: "Tag/4994"},
{_from: "Person/35184372096260", _to: "Tag/5116"},
{_from: "Person/35184372096260", _to: "Tag/5446"},
{_from: "Person/35184372096260", _to: "Tag/5531"},
{_from: "Person/35184372096260", _to: "Tag/5677"},
{_from: "Person/35184372096260", _to: "Tag/6369"},
{_from: "Person/35184372096260", _to: "Tag/7340"},
{_from: "Person/35184372096260", _to: "Tag/7756"},
{_from: "Person/35184372096260", _to: "Tag/7853"},
{_from: "Person/35184372096260", _to: "Tag/8219"},
{_from: "Person/35184372096260", _to: "Tag/8481"},
{_from: "Person/35184372096260", _to: "Tag/9738"},
{_from: "Person/35184372096260", _to: "Tag/9868"},
{_from: "Person/35184372096260", _to: "Tag/10410"},
{_from: "Person/35184372096260", _to: "Tag/11121"},
{_from: "Person/35184372096260", _to: "Tag/11211"}]
FOR hasInterestEdge IN hasInterestEdges INSERT hasInterestEdge INTO hasInterest
LET studyAtEdges = [
{_from: "Person/35184372096260", _to: "Organisation/1980", classYear: 2004}]
FOR studyAtEdge IN studyAtEdges INSERT studyAtEdge INTO studyAt
LET workAtEdges = [
{_from: "Person/35184372096260", _to: "Organisation/205", workFrom: 2006},
{_from: "Person/35184372096260", _to: "Organisation/209", workFrom: 2005}]
FOR workAtEdge IN workAtEdges INSERT workAtEdge INTO workAt
通过 java 驱动程序,您可以使用 collection.insertDocuments
命令并传递要插入的文档数组。请参阅文档 here
在http接口中可以使用
POST /_api/document/{collection}
并传递 json 和文档数组,如 here 所述(参见创建文档部分)
最后,直接在 AQL 中,您通常会使用 FOR doc in [arrayOfDocs] insert {<stuff>} into collection
下面是直接在 Web GUI 中插入 AQL 运行 中的多条记录的示例:
let Params =[ {personId:35184372096260, firstName:'André', lastName:'Atem'}, {personId:35184372096261, firstName:'Robert', lastName:'Smith'} ]
for item in Params
insert item into test5
系统设置
- ArangoDB: v3.4.7
- Java驱动程序:v5.0.0
问题
我正在尝试在 ArangoDB 的单个查询中执行多个插入。具体如下:
INSERT { _key: @personId, firstName: @firstName, lastName: @lastName, gender: @gender, birthday: @birthday, birthday_day: @birthday_day, birthday_month: @birthday_month, creationDate: @creationDate, locationIP: @locationIP, browserUsed: @browserUsed, email:
@email, speaks: @speaks } INTO Person
INSERT { _from: Person/@personId, _to: Place/@placeId } INTO isLocatedIn
INSERT { _from: Person/@personId, _to: Tag/@tag0Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag1Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag2Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag3Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag4Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag5Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag6Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag7Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag8Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag9Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag10Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag11Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag12Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag13Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag14Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag15Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag16Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag17Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag18Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag19Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag20Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Tag/@tag21Id } INTO hasInterest
INSERT { _from: Person/@personId, _to: Organisation/@studyOrg0Id, classYear: @classYear0 } INTO studyAt
INSERT { _from: Person/@personId, _to: Organisation/@workOrg0Id, classYear: @workFrom0 } INTO workAt
INSERT { _from: Person/@personId, _to: Organisation/@workOrg1Id, classYear: @workFrom1 } INTO workAt
使用以下参数:
Params: {personId=35184372096260, firstName=André, lastName=Atem, gender=female, birthday=501897600000, birthday_day=27, birthday_month=11, creationDate=1347546700674, locationIP=41.205.16.11, browserUsed=Internet Explorer, email=[Andre35184372096260@yahoo.com], speaks=
[en], placeId=1048, tag0Id=285, tag1Id=441, tag2Id=1761, tag3Id=2019, tag4Id=2800, tag5Id=2832, tag6Id=4994, tag7Id=5116, tag8Id=5446, tag9Id=5531, tag10Id=5677, tag11Id=6369, tag12Id=7340, tag13Id=7756, tag14Id=7853, tag15Id=8219, tag16Id=8481, tag17Id=9738, tag18Id=98
68, tag19Id=10410, tag20Id=11121, tag21Id=11211, studyOrg0Id=1980, classYear0=2004, workOrg0Id=205, workFrom0=2006, workOrg1Id=209, workFrom1=2005}
但是当我尝试这样做时,出现以下错误:
Exception in thread "main" com.arangodb.ArangoDBException: Response: 400, Error: 1579 - AQL: access after data-modification by collection 'Person' (while optimizing ast)
at com.arangodb.internal.util.ResponseUtils.checkError(ResponseUtils.java:53)
at com.arangodb.internal.velocystream.VstCommunication.checkError(VstCommunication.java:146)
at com.arangodb.internal.velocystream.VstCommunicationSync.execute(VstCommunicationSync.java:128)
at com.arangodb.internal.velocystream.VstCommunicationSync.execute(VstCommunicationSync.java:42)
at com.arangodb.internal.velocystream.VstCommunication.execute(VstCommunication.java:129)
at com.arangodb.internal.velocystream.VstProtocol.execute(VstProtocol.java:47)
at com.arangodb.internal.ArangoExecutorSync.execute(ArangoExecutorSync.java:71)
at com.arangodb.internal.ArangoExecutorSync.execute(ArangoExecutorSync.java:53)
at com.arangodb.internal.ArangoDatabaseImpl.query(ArangoDatabaseImpl.java:197)
似乎在 ArangoDB 中我不能在一个查询中向同一个集合插入两次?我是否需要为每个 INSERTS 执行单独的查询?
感谢您的帮助!
解决方案
使用 FOR
结构重新表述 AQL 查询解决了问题:
INSERT { _key: @personId, firstName: @firstName, lastName: @lastName, gender: @gender, birthday: @birthday, birthday_day: @birthday_day, birthday_month: @birthday_month, creationDate: @creationDate, locationIP: @locationIP, browserUsed: @browserUsed, email: @email, speaks: @speaks } INTO Person
LET hasInterestEdges = [
{_from: "Person/35184372096260", _to: "Tag/285"},
{_from: "Person/35184372096260", _to: "Tag/441"},
{_from: "Person/35184372096260", _to: "Tag/1761"},
{_from: "Person/35184372096260", _to: "Tag/2019"},
{_from: "Person/35184372096260", _to: "Tag/2800"},
{_from: "Person/35184372096260", _to: "Tag/2832"},
{_from: "Person/35184372096260", _to: "Tag/4994"},
{_from: "Person/35184372096260", _to: "Tag/5116"},
{_from: "Person/35184372096260", _to: "Tag/5446"},
{_from: "Person/35184372096260", _to: "Tag/5531"},
{_from: "Person/35184372096260", _to: "Tag/5677"},
{_from: "Person/35184372096260", _to: "Tag/6369"},
{_from: "Person/35184372096260", _to: "Tag/7340"},
{_from: "Person/35184372096260", _to: "Tag/7756"},
{_from: "Person/35184372096260", _to: "Tag/7853"},
{_from: "Person/35184372096260", _to: "Tag/8219"},
{_from: "Person/35184372096260", _to: "Tag/8481"},
{_from: "Person/35184372096260", _to: "Tag/9738"},
{_from: "Person/35184372096260", _to: "Tag/9868"},
{_from: "Person/35184372096260", _to: "Tag/10410"},
{_from: "Person/35184372096260", _to: "Tag/11121"},
{_from: "Person/35184372096260", _to: "Tag/11211"}]
FOR hasInterestEdge IN hasInterestEdges INSERT hasInterestEdge INTO hasInterest
LET studyAtEdges = [
{_from: "Person/35184372096260", _to: "Organisation/1980", classYear: 2004}]
FOR studyAtEdge IN studyAtEdges INSERT studyAtEdge INTO studyAt
LET workAtEdges = [
{_from: "Person/35184372096260", _to: "Organisation/205", workFrom: 2006},
{_from: "Person/35184372096260", _to: "Organisation/209", workFrom: 2005}]
FOR workAtEdge IN workAtEdges INSERT workAtEdge INTO workAt
通过 java 驱动程序,您可以使用 collection.insertDocuments
命令并传递要插入的文档数组。请参阅文档 here
在http接口中可以使用
POST /_api/document/{collection}
并传递 json 和文档数组,如 here 所述(参见创建文档部分)
最后,直接在 AQL 中,您通常会使用 FOR doc in [arrayOfDocs] insert {<stuff>} into collection
下面是直接在 Web GUI 中插入 AQL 运行 中的多条记录的示例:
let Params =[ {personId:35184372096260, firstName:'André', lastName:'Atem'}, {personId:35184372096261, firstName:'Robert', lastName:'Smith'} ]
for item in Params
insert item into test5