Я использую MongoDb на C#. Ниже показан объект, который я хочу клонировать, но также хочу объединить его в одну коллекцию.
Это упрощенная версия документа, который я использую:
class MyDocument
{
public ObjectId Id { get; set; } // my object id. see my question below, type can change
public string MyDocId { get; set; }
public int ContainerId { get; set; } // child of owner so linked
public string OwnerId { get; set; } // this is guid but stored as string for mongodb
}
Объект уникален
только по идентификатору
комбинации OwnerId + MyDocId + ContainerId, поэтому допустимыми примерами являются ("12AF", "John", 1), ("12AF", "Anna", 1), ("12AF", "John", 2), («34AF», «Джон», 2) и так далее, но я не могу добавить еще один («12AF», «Джон», 1), потому что он уже существует.
Я хочу клонировать все OwnerId+ContainerId 12AF+1 и в 12AF+3. В моем примере я хочу получить:
Я думаю, что смогу сделать это с помощью операторов агрегирования и слияния, без проблем.
На самом деле я хочу иметь другое поле Id. Предполагается, что это строка, и она будет такой, как показано здесь: (Id, OwnerId, MyDocId, ContainerId) в формате
Представьте, что я хочу сделать: клонирование объектов контейнера 1 (владелец 12AF) в контейнер 3, поэтому мне также нужно обновить поля ID, как показано здесь:
Возможно ли это без загрузки всех объектов в мое приложение? (загрузите их в память приложения, выполните итерацию для обновления каждого поля идентификатора, а затем вставьте снова. это не то, что я хочу)
Мне бы очень хотелось иметь это поле идентификатора, подобное этому, для поиска в другом приложении, где поля идентификатора установлены в этом формате. Если я смогу решить эту проблему, идентификаторы обоих приложений будут совпадать. Я не могу изменить другое приложение, поэтому я привязан к своей модели документа.
В SQL это очень просто, потому что мы можем использовать конкатенацию строк, как показано здесь, просто чтобы дать представление. Я хочу повторить это с помощью MongoDb.
var pipeline = new[]
{
new BsonDocument("$match", new BsonDocument("Container", 1)),
new BsonDocument("$set", new BsonDocument("Container", 4)),
new BsonDocument("$set", new BsonDocument("Path", new BsonDocument("$concat", new BsonArray{ "$Container", ":", "$Name" }))),
new BsonDocument("$project", new BsonDocument("_id", 0)),
new BsonDocument("$merge", new BsonDocument
{
{ "into", "sample" },
{ "whenMatched", "fail" },
{ "whenNotMatched", "insert" }
})
};
await collection.AggregateAsync(pipeline);
concat может использовать только строку, а не целое число, хотя у него есть ограничения.
Я использую MongoDb на C#. Ниже показан объект, который я хочу клонировать, но также хочу объединить его в одну коллекцию. Это упрощенная версия документа, который я использую: [code]class MyDocument { public ObjectId Id { get; set; } // my object id. see my question below, type can change public string MyDocId { get; set; } public int ContainerId { get; set; } // child of owner so linked public string OwnerId { get; set; } // this is guid but stored as string for mongodb } [/code] Объект уникален [list] [*]только по идентификатору [*]комбинации OwnerId + MyDocId + ContainerId, поэтому допустимыми примерами являются ("12AF", "John", 1), ("12AF", "Anna", 1), ("12AF", "John", 2), («34AF», «Джон», 2) и так далее, но я не могу добавить еще один («12AF», «Джон», 1), потому что он уже существует. [/list] Я хочу клонировать все OwnerId+ContainerId 12AF+1 и в 12AF+3. В моем примере я хочу получить: [code]("12AF", "John", 1) ("12AF", "Anna", 1) ("12AF", "John", 2) ("34AF", "John", 2) ("12AF", "John", 3) ("12AF", "Anna", 3) [/code] Я думаю, что смогу сделать это с помощью операторов агрегирования и слияния, без проблем. На самом деле я хочу иметь другое поле Id. Предполагается, что это строка, и она будет такой, как показано здесь: (Id, OwnerId, MyDocId, ContainerId) в формате [code]("12AF\\1:John", "12AF", "John", 1) ("12AF\\1:Anna", "12AF", "Anna", 1) ("12AF\\2:John", "12AF", "John", 2) ("34AF\\2:John", "34AF", "John", 2) [/code] Представьте, что я хочу сделать: клонирование объектов контейнера 1 (владелец 12AF) в контейнер 3, поэтому мне также нужно обновить поля ID, как показано здесь: [code]("12AF\\1:John", "12AF", "John", 1) ("12AF\\1:Anna", "12AF", "Anna", 1) ("12AF\\2:John", "12AF", "John", 2) ("34AF\\2:John", "34AF", "John", 2) ("12AF\\3:John", "12AF", "John", 3) ("12AF\\3:Anna", "12AF", "Anna", 3) [/code] Возможно ли это без загрузки всех объектов в мое приложение? (загрузите их в память приложения, выполните итерацию для обновления каждого поля идентификатора, а затем вставьте снова. это не то, что я хочу) Мне бы очень хотелось иметь это поле идентификатора, подобное этому, для поиска в другом приложении, где поля идентификатора установлены в этом формате. Если я смогу решить эту проблему, идентификаторы обоих приложений будут совпадать. Я не могу изменить другое приложение, поэтому я привязан к своей модели документа. В SQL это очень просто, потому что мы можем использовать конкатенацию строк, как показано здесь, просто чтобы дать представление. Я хочу повторить это с помощью MongoDb. [code]INSERT INTO MT_TABLE (Id, MyDocId, ContainerId, OwnerId) SELECT OwnerId + '\\' + @newContainerId + ':' + MyDocId, MyDocId, @newContainerId, OwnerId FROM MT_TABLE WHERE ContainerId = @oldContainerId AND OwnerId = @ownerId [/code] решение 1, без создания идентификатора [code]var pipeline = new EmptyPipelineDefinition() .Match(Builders.Filter.Eq(x => x.Container, 1)) .Set(Builders.SetFields.Set(x => x.Container, 4)) .Project(Builders.Projection.Exclude(x => x.Id)) .Merge(collection, new MergeStageOptions { WhenMatched = MergeStageWhenMatched.Fail, WhenNotMatched = MergeStageWhenNotMatched.Insert });
await collection.AggregateAsync(pipeline); [/code] решение 2, с созданием идентификатора. concat требует использования BsonDocument [code]var pipeline = new[] { new BsonDocument("$match", new BsonDocument("Container", 1)), new BsonDocument("$set", new BsonDocument("Container", 4)), new BsonDocument("$set", new BsonDocument("Path", new BsonDocument("$concat", new BsonArray{ "$Container", ":", "$Name" }))), new BsonDocument("$project", new BsonDocument("_id", 0)), new BsonDocument("$merge", new BsonDocument { { "into", "sample" }, { "whenMatched", "fail" }, { "whenNotMatched", "insert" } }) }; await collection.AggregateAsync(pipeline); [/code] concat может использовать только строку, а не целое число, хотя у него есть ограничения.