这应该是 2 分钟就能快速找到的,但我搜索了一个小时却找不到任何解决方案。
我如何将
username
字段中每个单词的第一个字母大写?
{
"_id" : ObjectId("5908288bfbce59540a67fa11"),
"username" : "JOHN DOE"
},
{
"_id" : ObjectId("5908288bfbce59540a67fa12"),
"username" : "jane doe"
}
尝试过这个解决方案,我不太明白,但它不起作用:
Fetched 0 record(s) in 0ms
db.getCollection('test').toupper.aggregate(
[
{
$project: {
username: {
$concat: [{
$toUpper: { $substr: ["$username", 0, 1] }
}, { $substr: ["$username", 1, 3] }]
}
}
}])
TL;博士
var map = {
"$map": {
"input": { "$split": [ "$username", " " ] },
"as": "name",
"in": {
"$concat": [
{ "$toUpper": { "$substrCP": ["$$name", 0, 1] } },
{
"$substrCP": [
"$$name",
1,
{ "$subtract": [{ "$strLenCP": "$$name" }, 1 ]}
]
}
]
}
}
};
db.getCollection('test').aggregate([
{
"$addFields": {
"username": {
"$concat": [
{ "$arrayElemAt": [map, 0] },
" ",
{ "$arrayElemAt": [map, 1] }
]
}
}
}
]);
$split
运算符按给定的分隔符分割字符串,在本例中分隔符将是空格:
示例
{ "$split": [ "jane doe", " " ] }
结果
[ "jane", "doe" ]
$map
运算符,并且对于数组中的每个元素,也使用 $toUpper
对子字符串应用 $substrCP
转换作为与 $concat
的连接过程,返回转换后的数组。
在转换中,您需要获取给定单词中的第一个字母,将该字母转换为大写,然后连接字符串的其余部分。
对于第一部分,转换如下:
示例
{ "$toUpper": { "$substrCP": ["jane", 0, 1] } }
结果
"J"
对于字符串的其余部分
示例
{
"$substrCP": [
"jane",
1,
{ "$subtract": [{ "$strLenCP": "jane" }, 1 ]}
]
}
结果
"ane"
示例
{
$concat: [
{ "$toUpper": { "$substrCP": ["jane", 0, 1] } },
{
"$substrCP": [
"jane",
1,
{ "$subtract": [{ "$strLenCP": "jane" }, 1 ]}
]
}
]
}
结果
"Jane"
$map
中使用以上:
示例
{
"$map": {
"input": { "$split": [ "jane doe", " " ] },
"as": "name",
"in": {
"$concat": [
{ "$toUpper": { "$substrCP": ["$$name", 0, 1] } },
{
"$substrCP": [
"jane",
1,
{ "$subtract": [{ "$strLenCP": "$$name" }, 1 ]}
]
}
]
}
}
}
结果
[ "Jane", "Doe" ]
$arrayElemAt
运算符的表达式,并再次使用 $concat
作为:
{
"$addFields": {
"username": {
"$concat": [
{ "$arrayElemAt": [map, 0] },
" ",
{ "$arrayElemAt": [map, 1] }
]
}
}
}
您的最终聚合操作将变为:
var map = {
"$map": {
"input": { "$split": [ "$username", " " ] },
"as": "name",
"in": {
"$concat": [
{ "$toUpper": { "$substrCP": ["$$name", 0, 1] } },
{
"$substrCP": [
"$$name",
1,
{ "$subtract": [{ "$strLenCP": "$$name" }, 1 ]}
]
}
]
}
}
};
db.getCollection('test').aggregate([
{
"$addFields": {
"username": {
"$concat": [
{ "$arrayElemAt": [map, 0] },
" ",
{ "$arrayElemAt": [map, 1] }
]
}
}
}
]);
注意: 尚未测试上述内容,但它至少应该为您提供一些如何解决问题的指导。
这是使用
$substrCP
和 $concat
作为 $map
的表达式的另一种选择。
当然,您需要
$toUpper
和他犯罪的兄弟 $toLower
将字符串转换为大写或小写
db.collection.aggregate([
{
"$addFields": {
"username": {
"$reduce": {
"input": {
"$map": {
"input": {
"$split": [
"$username",
" "
]
},
"in": {
"$concat": [
{
"$toUpper": {
"$substrCP": [
"$$this",
0,
1
]
}
},
{
"$toLower": {
"$substrCP": [
"$$this",
1,
{ "$strLenCP": "$$this" }
]
}
}
]
}
}
},
"initialValue": "",
"in": {
"$concat": [
"$$value",
" ",
"$$this"
]
}
}
}
}
}
]
)
这是我针对我的情况的解决方案,我必须在气味中转义“and”或“of”
var map = {
"$map": {
"input": { "$split": [{$trim: {input:"$label",chars:" "}}, " " ] },
"as": "name",
"in": {
$cond:[
{$in:["$$name",['of','and']]},
"$$name",
{
"$concat": [
{ "$toUpper": { "$substrCP": ["$$name", 0, 1] } },
{
"$substrCP": [
"$$name",
1,
{ "$subtract": [{ "$strLenCP": "$$name" }, 1 ]}
]
}
]
}
]
}
}
};
db.getCollection('secondaryskills').aggregate([/*{$match:{ "label" : "Endpoint Detection & Response"}},*/
{
"$project": {
"label": {
$trim:{
input:{
$reduce : {
input:map,
initialValue: "",
in: { $concat : ["$$value", " " , "$$this"] }
}
},
chars:" "
}
}
}
}
]);