Есть ли способ сопоставить параметры, переданные с помощью Merge?
В идеале я хочу сделать следующее:
Объединить узел (создать, если он не существует, или обновить все свойства узла, которые являются динамическими)
MERGE (c:Label {Id: {map}.Id}) SET c = {map}
Это можно легко сделать, когда карта представляет собой отдельный объект, и вы обновляете только один узел, но мне бы хотелось иметь возможность делать это как массовую операцию.
Передать список и получить эту автоматическую карту.
Конечно, я не думаю, что в настоящее время это возможно с помощью Cypher Merge, но это можно сделать с помощью пакетных методов REST API, однако неясно, как создать пакет с помощью Neo4jClient.
Если возможно, как можно построить пакет операций слияния? Я мог бы перечислить список и для каждого объекта добавить в пакет операцию слияния. Затем выполните пакет целиком.
Любая помощь будет потрясающей!
Обновить Итак, странный побочный эффект - когда я запускаю этот код:
createUniqueConstraint(label, PK_Field);
string propKey = label + "s" ;
//string createstr = string.Format("(e:{0} {{{1}}})", label, propKey);
string strForEach = string.Format("(n in {{{0}}} | MERGE (c:{1} {{{2} : n.{2}}}) SET c = n)",
propKey, label, PK_Field);
foreach (var entities in Neo4jDataRepository.Batch(list, 1000))
{
var query = client
.Cypher
.ForEach(strForEach)
.WithParam(propKey, entities.ToList());
query.ExecuteWithoutResults();
Debug.WriteLine("Batch passed for " + label + " ("+list.Count()+" items)");
break;
}
Это работает нормально (вроде). У меня есть связанные узлы, которые также содержат свойство с тем же именем, что и PK_Field, и в итоге я получаю узлы с одним свойством вместо всего объекта.
Пример: Contact {ContactId:1,name:"David"} является одной из моделей объекта ContactMembership {ContactMembershipId: 1, ContactId: 1, ContactMembershipTypeId: 1} ContactMembershipType {ContactMembershipType: 1, name: "User"}
При запуске этого кода он сначала перебирает каждый массив моделей и добавляет/обновляет модели в БД, используя приведенный выше оператор слияния. После того, как все модели находятся в базе данных, он запускает вызов метода отношения, который берет связанную модель данных ContactMembership и повторяет ее, используя этот код:
public void CreateNewRelationshipsFromMatrix<T>(IEnumerable<T> relationshipMatrix, string IDFieldLeft, string IDFieldRight)
where T : BaseModel
{
string entityName = GetTypeName(default(T)); //i.e. ContactAddress
string merge1 = string.Format("(c:{0} {{{1}:row.{2}}})", IDFieldLeft.Replace("Id", ""), IDFieldLeft, IDFieldLeft);
string merge2 = string.Format("(a:{0} {{{1}:row.{2}}})", IDFieldRight.Replace("Id", ""), IDFieldRight, IDFieldRight);
string merge3 = string.Format("(c)-[r:{0}Link]->(a)", entityName);
string uniqueRelationshipSetter = " ON CREATE SET r.weight=1 ON MATCH SET r.weight = r.weight + 1 ";
foreach (var list in Neo4jDataRepository.Batch(relationshipMatrix, 1000))
{
var q1 = client.Cypher.Merge(merge1);
var q2 = client.Cypher.Merge(merge2);
var q3 = client.Cypher.Merge(merge3);
var query = client
.Cypher
.WithParam("coll", list.ToList())
.ForEach("(row in {coll} | " +
q1.Query.QueryText + " " +
q2.Query.QueryText + " " +
q3.Query.QueryText + ")");
query.ExecuteWithoutResults();
}
}
Похоже, что во время этого второго вызова (соотношения уже существующих узлов) система создает новые узлы с помощью Label :Contact только со свойством ContactId и без каких-либо других данных. ПОИСКПОЗ (n:Contact)-[:ContactMembership]-(t) всегда возвращает эту модель ContactId для n, а не полную модель контакта.
ПОИСКПОЗ (n)-[:ContactMembership]-(t) вернет полную модель как для t, так и для n.
Непонятно, что здесь происходит....