在MongoDB中,多个位置标识符最经济的替代方法是什么?

时间:2019-02-26 08:18:05

标签: mongodb mongoose mongodb-query

我有一个名为 authors 的集合,该集合具有以下架构:

authors: {
  _id,
  firstName,
  lastName,
  posts: [
    post 1: {...},
    post 2: {...},
    post 3: {
      _id,
      title,
      content,
      tags: [
        tag 1: {...},
        tag 2: {...},
        tag 3: {
          _id,
          name,
          description,
        },
      ],
    },
  ],
}

可以看出,帖子 authors 集合中的一组对象。反过来,此数组中的每个对象都有标签,这是另一个对象数组。每个标签对象都有三个字段: _id 名称说明

我正在尝试编写一个GraphQL变体来更新集合中匹配文档上的 name 字段。

    const updatedTagInAuthor = await Author
  .updateMany({ 'posts.tags._id': args.newTagInfo._id },
    {
      $set: {
        'posts.$.tags.$.name': args.newTagInfo.name,
        'posts.$.tags.$.description': args.newTagInfo.description,
      },
    }, opts);

上面的代码段显然失败了,因为MongoDB在查询中不允许多个位置元素( $ )。那么,有什么经济的选择可以完成我想做的事情?

我尝试了MongoDB建议的 ArrayFilter 方法:

           const updatedTagInAuthor = await Author.update(
              {},
              { $set: { 'posts.$[].tags.$[tag].name': args.newTagInfo.name } },
              { arrayFilters: [{ 'tag._id': args.newTagInfo._id }], multi: true }
            );

但这会引发以下错误:

  

无法读取未定义的属性“ castForQuery”

还是很困惑!

2 个答案:

答案 0 :(得分:1)

这些是我正在使用给出的查询来更新的文档,

{"name" : "Steve","details" : [ {
        "work" : [ {
                "Company" : "Byjus",
                "id" : 1,
                "country" : "India"
            }, 
            {
                "Company" : "Vodafone",
                "id" : 2,
                "country" : "UK"
            }]
    }]},{"name" : "Virat","details" : [ {
        "work" : [ {
                "Company" : "Byjus",
                "id" : 1,
                "country" : "India"
            }, 
            {
                "Company" : "Verizon",
                "id" : 3,
                "country" : "US"
            }]
    }]}

QUERY:

db.getCollection('Users').update({"details": {"$elemMatch": {"work.id": 1}}}, {'$set': {'details.$[].work.$.Company': 'Boeing', 'details.$[].work.$.country': 'US'} }, {multi: true});

这与您问的正确吗? 尝试将这两个文档插入名为User的集合中,然后直接在Mongo CONSOLE中而不是在GUI中尝试上述查询。完全使用查询,而不仅仅是$ set方法。

答案 1 :(得分:0)

尝试一下

Author.update({"posts": { "$elemMatch": { "tags.id": args.newTagInfo._id } }}, 
    {'$set': {'posts.$[].tags.$.name': args.newTagInfo.name, 'posts.$[].tags.$.description': args.newTagInfo.description} }, 
    {multi: true});