Mongo-go, как использовать arrayFilter, чтобы найти элемент в «массиве объектов внутри массива объектов» - PullRequest
1 голос
/ 25 мая 2019

Представим себе JSON-подобие:

"user": {
  "id": "1234",
  ...some fields,
  "achievements": [
    {
      "scope": "life achievements",
      "list": [
        {"_id": 1, "title": "some text", "gotAt": "some date"},
        {"_id": 2, "title": "some other text", "gotAt": "some date"}
      ]
    },
    {
      "scope": "sport achievements",
      "list": [
        {"_id": 1, "title": "sport", "gotAt": "some date"},
        {"_id": 2, "title": "some other sport", "gotAt": "some date"}
      ]
    },
    {
      "scope": "academic achievements",
      "list": [
        {"_id": 1, "title": "some text", "gotAt": "some date"},
        {"_id": 2, "title": "some other text", "gotAt": "some date"}
      ]
    },
  ]
}

Мне нужно ОБНОВИТЬ, например, первое жизненное достижение (с идентификатором 1), используя для этого mongoDb и драйвер Golang Mongo-go

проблема в уровне вложенности.Я могу получить некоторый элемент массива оператором $ mongoDb, но здесь мне нужно идентифицировать каждое пользовательское достижение по сфере деятельности (жизнь, спорт, учеба и т. Д.) И области достижений _id.Поэтому мне нужно выполнить поиск внутри массива объектов внутри другого массива объектов.

Это то, что я сделал (это все равно не работает)

doc := coll.FindOneAndUpdate(
        context.Background(),
        bson.D{
            {"_id", "1234"},
            {"achievements.scope", "life achievements"},
            {"achievements.list._id", 1},
        },
        bson.D{
            {"$set", bson.D{
                {"achievements.$.list.$[elem].title", "some new test"},
            }},
        },
        options.FindOneAndUpdate().SetArrayFilters(options.ArrayFilters{
            Filters: append(make([]interface{}, 0), bson.D{
                {"elem", bson.D{
                    {"achievements.list._id", 1},
                }},
            }),
        }).SetReturnDocument(1),
    )

Я ожидаю, что этот запрос будет обновляться толькоодин элемент, указанный в полях "id" и "scope".Может быть, я некорректно использую arrayFilters или неправильно установил параметр функции FindOneAndUpdate.Теперь он не выдает никаких ошибок и не обновляет документ.Пожалуйста, помогите мне

Ответы [ 2 ]

0 голосов
/ 26 мая 2019

Итак, с помощью @owlwalks мы нашли решение:

doc := coll.FindOneAndUpdate(
        context.Background(),
        bson.D{
            {"_id", "1234"},
            {"achievements.scope", "life achievements"},
        },
        bson.D{
            {"$set", bson.D{
                {"achievements.$.list.$[elem].title", "some new text"},
            }},
        },
        options.FindOneAndUpdate().SetArrayFilters(options.ArrayFilters{
            Filters: []interface{}{bson.D{
                    {"elem._id", 1},
                }},
        }).SetReturnDocument(1),
    )
0 голосов
/ 26 мая 2019

попробуйте это:

Монго-гоу-водитель:

coll.FindOneAndUpdate(
    context.Background(),
    bson.D{
        {"id", "1234"},
        {"achievements.scope", "life achievements"},
        {"achievements.list._id", 1},
    },
    bson.M{"$set": bson.M{"achievements.$.list.$[elem].title"": "some new test"}},
    options.FindOneAndUpdate().SetArrayFilters(options.ArrayFilters{
        Filters: []interface{}{bson.M{"elem._id": 1}},
    }),
)

который "переводит" в оболочку:

db.user.findOneAndUpdate(
  {"id": "1234","achievements.scope": "life achievements","achievements.list._id": 1},
  {$set: {"achievements.$.list.$[elem].title": "some new test"}},
  { arrayFilters: [  { "elem._id": 1 } ]}
)
...