I have some data in a MongoDB collection that looks something like this:
db.test.insertOne(
{ "interactions": [
{
data: "keep",
prompt: "prompt 1"
},
{
other: "keep",
prompt: "prompt 2"
},
{
field: "no prompt"
}
]}
)
I want to iterate over all the interactions
, and set prompts
to an array containing the current value of prompt
. Something like this:
{
"interactions": [
{
"data": "keep",
"prompt": "prompt 1",
"prompts": [ "prompt 1" ]
},
{
"other": "keep",
"prompt": "prompt 2",
"prompts": [ "prompt 2" ]
},
{
"field": "no prompt"
}
]
}
I’ve been trying to do a updateMany()
with an aggregation pipeline, but am getting an error that I don’t understand. This is my update:
db.test.updateMany(
{},
[{
$set: {
interactions: {
$map: {
input: "$interactions",
as: "interaction",
in: {
$mergeObjects: [
"$$interaction",
{
$cond: {
if: { "$$interaction.prompt": { $exists: true } },
then: {
prompts: [ "$$interaction.prompt" ]
},
else: {}
}
}
]
}
}
}
}
}]
)
Running this I get an error:
Unrecognized expression ‘$$interaction.prompt’.
Running the update without the $cond
works:
db.test.updateMany(
{},
[{
$set: {
interactions: {
$map: {
input: "$interactions",
as: "interaction",
in: {
$mergeObjects: [
"$$interaction",
{
prompts: [ "$$interaction.prompt" ]
}
]
}
}
}
}
}]
)
but after that operation, the array element that didn’t have a prompt
has an array with a null
value:
{
"interactions": [
{
"data": "keep",
"prompt": "prompt 1",
"prompts": ["prompt 1"]
},
{
"other": "keep",
"prompt": "prompt 2",
"prompts": ["prompt 2"]
},
{
"field": "no prompt",
"prompts": [null]
}
]
}
I don’t want prompts
set on an element that didn’t have prompt
.
So why can’t I access $$interactions.prompt
within the $cond
?
Alternatively, if there’s a better way to accomplish what I want to do, please let me know.
2
Answers
For some reason, using
$not
and$in
didn't work in my database, although it did in the Playground. After finding an alternative here: https://stackoverflow.com/a/25515046/1303158, my final solution is:Demo @ Mongo Playground
In the aggregation pipeline, you can’t use the
$exists
operator.And you must start with the
$
operator but not with variable$$
.Instead, you check whether
$$interaction.prompt
is neitherundefined
nornull
.Demo @ Mongo Playground