问题
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