Обновление данных встроенного документа в MongoDB - PullRequest
7 голосов
/ 02 апреля 2011

В MongoDB, если у меня есть следующая структура документа:

{ "_id" : { "$binary" : "jchPoPd7PUS1w+sR7is23w==", "$type" : "03" }, 
"companies" : 
  [
    { "_id" : { "$binary" : "jchPoPd7PUS1w+sR7is23w==", "$type" : "03" },
       "name" : "Google" },
    { "_id" : { "$binary" : "jchPoPd7PUS1w+sR7is23w==", "$type" : "03" }, 
       "name" : "Greenfin" }, 
    { "_id" : { "$binary" : "jchPoPd7PUS1w+sR7is23w==", "$type" : "03" },
       "name" : "Zynet"   }
 ],
 "firstname" : "Peter", 
 "surname" : "Smith" }

(т. Е. Документ Person с массивом Companies, встроенным в документ человека), тогда как мне обновить ВСЕ вхождения определенной компании (с указанием идентификатора компании _id) с помощью одного запроса + обновление?

Я пробовал следующее:

MongoCollection personCollection = mdb.GetCollection("person");
BsonBinaryData bin = new BsonBinaryData(new Guid("0AE91D6B-A8FA-4D0D-A94A-91D6AC9EE343"));
QueryComplete query = Query.EQ("companies._id", bin);
var update = Update.Set("companies.name", "GreenfinNewName");
SafeModeResult result = personCollection.Update(query, update, UpdateFlags.Multi);

но это не работает. Я предполагаю, что мой вопрос сводится к двум вопросам: как мне нацелить встроенные компании в первоначальном запросе, а затем, как мне установить новое название компании в операторе Set. Примечание. В этом примере я выбрал «денормализацию» данных компании и встраивание их в документ каждого человека, поэтому может быть несколько документов человека с одним и тем же идентификатором и названием компании. Большое спасибо.

UPDATE: Используя технику Bugai13, я стал ближе. Это работает:

MongoCollection personCollection = mdb.GetCollection("person");
QueryComplete query = Query.EQ("companies.name", "Bluefin");
var update = Update.Set("companies.$.companynotes", "companynotes update via name worked");
SafeModeResult result = personCollection.Update(query, update, UpdateFlags.Multi, SafeMode.True);

Но это не работает:

MongoCollection personCollection = mdb.GetCollection("person");
BsonBinaryData bin = new BsonBinaryData(new Guid("0AE91D6B-A8FA-4D0D-A94A-91D6AC9EE343"));
Builders.QueryComplete query = Query.EQ("companies._id", bin);
var update = Update.Set("companies.$.companynotes", "companynotes update via id worked");
SafeModeResult result = personCollection.Update(query, update, UpdateFlags.Multi, SafeMode.True);

Итак, я пока не могу обновить с помощью первичного ключа, что мне и нужно сделать ...

Ответы [ 2 ]

9 голосов
/ 02 апреля 2011

Полагаю, вам стоит взглянуть на позиционный оператор в mongodb:

var update = MongoDB.Driver.Builders.Update
                                 .Set("companies.$.name", "GreenfinNewName");
                                                 ^^
                                            all magic here

Примечание: приведенный выше код обновит только first соответствующий элемент в массиве.Таким образом, если у вас есть две компании во вложенном массиве с name = GreenfinNewName, код выше будет обновлять только первое совпадение.

Примечание: UpdateFlags.Multi означает несколько документов, но не несколько элементов во вложенном массиве.

Обновление:

QueryComplete query = Query.EQ("companies._id", 
    BsonValue.Create(new Guid("0AE91D6B-A8FA-4D0D-A94A-91D6AC9EE343")));
var update = Update.Set("companies.$.companynotes", "companynotes");
personCollection.Update(query, update, UpdateFlags.Multi, SafeMode.True);

Надеюсь, эта помощь!

0 голосов
/ 12 апреля 2011

Просто хотел сказать спасибо вам обоим.Я изучаю Mongo, и эта ветка помогла.

Я использую драйвер 10gen C #, и для справки это мой код:

        MongoServer mongo = MongoServer.Create();

        MongoDatabase db = mongo.GetDatabase("test");

        MongoCollection<BsonDocument> coll = db["contacts"];

        BsonDocument doc = new BsonDocument();

        doc["FirstName"] = "Daniel";
        doc["LastName"] = "Smith";
        doc["Address"] = "999 Letsby Avenue";
        doc["City"] = "London";
        doc["County"] = "Greater London";
        doc["Postcode"] = "N13";

        coll.Insert<BsonDocument>(doc);

        QueryComplete qSel = Query.EQ("Postcode", "N13");

        MongoCursor<BsonDocument> cur = coll.Find(qSel);
        foreach (BsonDocument bdoc in cur)
        {
            Console.WriteLine(bdoc["FirstName"] + ":" + bdoc["Address"]);
        }


        UpdateBuilder docTwo = Update.Set("Postcode", "MK10");

        coll.Update(qSel, docTwo, UpdateFlags.Multi);

        QueryDocument qSel2 = new QueryDocument("FirstName", "Daniel");

        MongoCursor<BsonDocument> cur2 = coll.Find(qSel2);
        foreach (BsonDocument bsdoc in cur2)
        {
            Console.WriteLine(bsdoc["FirstName"] + " : " + bsdoc["Postcode"]);
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...