Reputation: 13
WHAT I WANT TO ACHIEVE
Let us say I have this object:
{
"_id" : ObjectId("5aec063380a7490014e88792"),
"personal_info" : {
"dialing_code": "+44",
"phone_number": "67467885664"
}
}
I need to concat the two values personal_info.dialing_code (+44) and phone_number (67467885664) into one. +4467467885664 and compare it to a value. I need to retrieve a specific record from the database that will match the said value.
PROBLEM
I am having trouble concatinating two fields inside a subdocument and I am receiving this error:
{
"name": "MongoError",
"message": "$concat only supports strings, not object",
"ok": 0,
"errmsg": "$concat only supports strings, not object",
"code": 16702,
"codeName": "Location16702"
}
ATTEMPT #1
I have tried this:
UserModel.aggregate([
{ $unwind: '$personal_info' },
{$project: {
concat_p: {$concat: [
'$personal_info.dialing_code',
'$personal_info.phone_number'
]}
}}
])
It is giving me an error as mentioned above and in result I cannot do a $match right after.
ATTEMPT #2
I also tried this:
UserModel.aggregate([
{ $unwind: '$personal_info' },
{$project: {
p_dialing_code: '$personal_info.dialing_code',
p_phone_number: '$personal_info.phone_number',
concat_p: {$concat: [
'$p_dialing_code',
'$p_phone_number'
]}
}}
])
I have successfully took out the subdocument values one level however when I tried concatinating, it is producing me null values. This is the result I am getting:
{
"_id": "5af0998036daa90014129d6e",
"p_dialing_code": "+44",
"p_phone_number": "13231213213244",
"concat_p": null
}
I know how to do it on the $match pipeline but I have no luck concatinating the values inside the subdocument. Clearly, I need to do this first before I can compare. Thanks
Upvotes: 0
Views: 1719
Reputation: 49975
It seems like you have different types under personal_info.dialing_code
and personal_info.phone_number
fields. In your example $concat
is applied to every document in your collection and that's why you're getting an exception since $concat
strictly expects its parameters to be strings
.
So it will be working fine for document posted in your question but will throw an exception for something like this:
{
"_id" : ObjectId("5aec063380a7490014e88792"),
"personal_info" : {
"dialing_code": {},
"phone_number": "67467885664"
}
}
One way to fix this is to add $match
condition before $project
and use $type operator to get only documents having strings
on those fields you want to concatenate.
db.UserModel.aggregate([
{
$match: {
$expr: {
$and: [
{ $eq: [ { $type: "$personal_info.dialing_code" }, "string" ] },
{ $eq: [ { $type: "$personal_info.phone_number" }, "string" ] }
]
}
}
},
{$project: {
concat_p: {$concat: [
"$personal_info.dialing_code",
"$personal_info.phone_number"
]}
}}
])
Upvotes: 1