What's the most economical alternative to multiple positional identifiers in MongoDB?

…衆ロ難τιáo~ 提交于 2019-12-24 23:23:57

问题


I have a collection named authors with the following schema:

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

As can be seen, posts is an array of objects inside the authors collection. Each object inside this array, in turn, has tags, another array of objects. And each of these tags objects has three fields: _id, name, and description.

I'm trying to write a GraphQL mutation to update this name field on matching documents in the collection.

    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);

The above snippet obviously fails since MongoDB doesn't allow multiple positional elements ($) in a query. So is there any economical alternative to accomplish what I'm trying to do?

I tried the ArrayFilter method as MongoDB suggests:

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

But this throws the following error:

Cannot read property 'castForQuery' of undefined

Still confused!


回答1:


These are the documents I'm updating with the kind of query I have given,

{"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});

It's similar to what you asked right? Try inserting those two Documents in a collection called User and try the above query in Mongo CONSOLE directly, not in GUI. Use the Query completely not just the $set method.




回答2:


Try this,

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


来源:https://stackoverflow.com/questions/54881039/whats-the-most-economical-alternative-to-multiple-positional-identifiers-in-mon

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!