programing

Mongo 업데이트 어레이 요소(.NET 드라이버 2.0)

jooyons 2023. 6. 19. 21:27
반응형

Mongo 업데이트 어레이 요소(.NET 드라이버 2.0)

편집: 자바스크립트 방식을 찾는 것이 아닙니다.저는 이것을 할 수 있는 MongoDBC# 2.0 드라이버 방법을 찾고 있습니다(가능하지 않을 수도 있다는 것을 알지만, 누군가 해결책을 알고 있기를 바랍니다).

나는 mongodb에 있는 주 문서의 배열에 포함된 항목의 값을 업데이트하려고 합니다.

저는 이것을 할 강력한 유형의 방법을 찾고 있습니다.Mongodbc# 2.0 드라이버를 사용하고 있습니다.

요소를 팝업하고 값을 업데이트한 다음 다시 삽입하면 됩니다.제가 그동안 작성되었을 수도 있는 내용을 덮어쓰고 있기 때문에, 이것은 단지 옳지 않은 것처럼 느껴집니다.

여기 제가 지금까지 시도했지만 운이 없었습니다.

private readonly IMongoCollection<TempAgenda> _collection;

void Main()
{
    var collectionName = "Agenda";
    var client = new MongoClient("mongodb://localhost:27017");
    var db = client.GetDatabase("Test");
    _collection = db.GetCollection<TempAgenda>(collectionName);
    UpdateItemTitle(1, 1, "hello");
}

public void UpdateItemTitle(string agendaId, string itemId, string title){
    var filter = Builders<TempAgenda>.Filter.Eq(x => x.AgendaId, agendaId);
    var update = Builders<TempAgenda>.Update.Set(x => x.Items.Single(p => p.Id.Equals(itemId)).Title, title);
    var result = _collection.UpdateOneAsync(filter, update).Result;
}

공식 문서(또는 다른 곳)에 언급되지 않았기 때문에 이 문제를 해결하는 데 시간이 걸렸습니다.하지만 저는 그들의 이슈 추적기에서 이것을 찾았습니다. 이것은 위치 연산자를 사용하는 방법을 설명합니다.$C# 2.0 드라이버를 사용합니다.

이렇게 하면 원하는 작업을 수행할 수 있습니다.

public void UpdateItemTitle(string agendaId, string itemId, string title){
    var filter = Builders<TempAgenda>.Filter.Where(x => x.AgendaId == agendaId && x.Items.Any(i => i.Id == itemId));
    var update = Builders<TempAgenda>.Update.Set(x => x.Items[-1].Title, title);
    var result = _collection.UpdateOneAsync(filter, update).Result;
}

주의:Item.Single()절이 로 변경되었습니다.Item.Any()필터 정의로 이동했습니다.

[-1]또는.ElementAt(-1)겉보기에는 특별하게 취급되며(모든 것이 < 0일 경우) 위치 연산자로 대체됩니다.$.

위의 내용이 이 쿼리로 변환됩니다.

db.Agenda.update({ AgendaId: 1, Items.Id: 1 }, { $set: { Items.$.Title: "hello" } })

감사합니다. 도움이 되었습니다.추가적으로, 위의 배열을 사용하여 중첩된 배열로 밀어넣고 하나에서 끌어냅니다.제가 발견한 문제는 PullFilter가 실제로 작동하지 않는 int 배열(개체가 아닌 단순 int 배열)이 있으면 "직렬화 정보를 확인할 수 없습니다"라는 것입니다. 이는 int 배열이기 때문에 이상합니다.결국 제가 한 것은 오직 하나의 int 매개변수를 가진 객체들의 배열을 만드는 것이었고, 모든 것이 작동하기 시작했습니다.버그일 수도 있고, 이해력이 부족할 수도 있습니다.어쨌든 C# 2.0 드라이버를 사용하여 중첩된 개체 어레이를 풀링하고 푸시하는 방법에 대한 정보를 찾기 위해 애를 썼기 때문에 위 구문을 사용하므로 여기에 결과를 게시해야 한다고 생각했습니다.

var filter = Builders<MessageDto>.Filter.Where(x => x._id == entity.ParentID && x.NestedArray.Any(i => i._id == entity._id));
var update = Builders<MessageDto>.Update.PullFilter(x => x.NestedArray.ElementAt(-1).User, Builders<User>.Filter.Eq(f => f.UserID, userID));
Collection<MessageDto>(currentUser).UpdateOneAsync(filter, update);

그리고 다음과 같습니다.

var filter = Builders<MessageDto>.Filter.Where(x => x._id == entity.ParentID && x.NestedArray.Any(i => i._id == entity._id));
var update = Builders<MessageDto>.Update.Push(x => x.NestedArray.ElementAt(-1).Users, new User { UserID = userID });
Collection<MessageDto>(currentUser).UpdateOneAsync(filter, update);

최신 드라이버에서ElementAt(-1)더 이상 지원되지 않을 수 있습니다.(-1)에 코드가 있어서 다음 작업 시 작동을 중지했습니다..NET6그리고.MongoDB Driver 2.19.0

대신 확장 방법을 도입했습니다.

x.A.FirstMatchingElement() => "A.$"
x.A.AllElements() => "A.$[]"
x.A.AllMatchingElements("identifier") => "A.$[identifier]"

문서 또는 하위 배열을 업데이트하는 올바른 방법은 다음과 같습니다.

var filter = Builders<Declaracion>.Filter.Where(x => x.Id == di && x.RemuneracionMensualActual.RemuneracionActIndustrial.Any(s => s.Id == oid));

        var update = Builders<Declaracion>.Update.Set(x => x.RemuneracionMensualActual.RemuneracionActIndustrial.ElementAt(-1).Ingreso, datos.ActividadIndustrial.Ingreso)
            .Set(x => x.RemuneracionMensualActual.RemuneracionActIndustrial.ElementAt(-1).RazonSocial, datos.ActividadIndustrial.RazonSocial)
            .Set(x => x.RemuneracionMensualActual.RemuneracionActIndustrial.ElementAt(-1).TipoNegocio, datos.ActividadIndustrial.TipoNegocio);

언급URL : https://stackoverflow.com/questions/31453681/mongo-update-array-element-net-driver-2-0

반응형