Как сказать... матч, когда поле - это число... в mongodb?
Итак, у меня есть поле под названием "город" в моих результатах... результаты повреждены, иногда это фактическое имя, иногда это число. Следующий код отображает все записи...
db.zips.aggregate([{$project : {city:{$substr:["$city",0,1]}}},{$sort : {city : 1}} ])
Мне нужно изменить эту строку, чтобы отображать только записи с городом, у которого есть имя, которое является числом (2,3,4 и т.д.).... Я думаю, что могу использовать '$ match', но как
db.zips.aggregate([{$project : {city:{$substr:["$city",0,1]}}},{$sort : {city : 1}}, {$match:{???what_to_say_here???} ])
Как сказать "матч, когда город является числом"?
я получаю выглядит так:
{
"city" : "A",
"_id" : "04465"
},
{
"city" : "1",
"_id" : "02821"
},
{
"city" : "0",
"_id" : "04689"
}
Я пытаюсь отобразить только записи с числовой строкой... это связано с большей проблемой "домашней работы", но я не могу даже дойти до фактического вопроса о домашнем задании, пока не получу этот момент.
Ответы
Ответ 1
Используйте $type
оператор в $match
:
db.zips.aggregate([
{$project : {city:{$substr:["$city",0,1]}}},
{$sort : {city : 1}},
{$match: {city: {$type: 16}}} // city is a 32-bit integer
]);
Для числа нет ни одного значения типа, поэтому вам нужно знать, какой тип номера у вас есть:
32-bit integer 16
64-bit integer 18
Double 1
Или используйте оператор $or
для соответствия всем типам чисел:
db.zips.aggregate([
{$project : {city:{$substr:["$city",0,1]}}},
{$sort : {city : 1}},
{$match: {$or: [{city: {$type: 1}}, {city: {$type: 16}}, {city: {$type: 18}}]}}
]);
Или даже используйте $not
для соответствия всем документам, где city
не является строкой:
db.zips.aggregate([
{$project : {city:{$substr:["$city",0,1]}}},
{$sort : {city : 1}},
{$match: {city: {$not: {$type: 2}}}} // city is not a string
]);
ОБНОВЛЕНО
Чтобы соответствовать всем документам, где city
является числовой строкой, вы можете использовать регулярное выражение:
db.zips.aggregate([
{$project : {city:{$substr:["$city",0,1]}}},
{$sort : {city : 1}},
{$match: {city: /^\d.*$/}} // city is all digits
]);
Ответ 2
Почему бы не использовать $regex?
db.zips.aggregate([
{$project : {city:{$substr:["$city",0,1]}}},
{$sort : {city : 1}},
{$match: {city:{$regex:'[0-9]'}}}
])
Ответ 3
Просто используйте:
db.zips.aggregate([
{$match: {
'city': { $regex: '^[0-9].*'}
}}])
Эта работа прекрасна для меня!
Ответ 4
Более простой способ сопоставить все документы, где city
- это числовая строка, использует свойство '0' <= city <= '9'
, то есть ваш запрос на агрегирование становится следующим:
db.zips.aggregate([
{$project : {city:{$substr:["$city",0,1]}}},
{$sort : {city : 1}},
{$match: {city: {$gte: '0', $lte: '9'}}}
]);
При использовании предложения JohnnyHK для регулярного выражения вы можете полностью сэкономить $project
.
Ответ 5
Вы также можете использовать команду in
db.zips.aggregate([
{
$project: {
first_char: {
$substr : ["$city",0,1]
},
"_id":"$_id"
}
},
{
$match: {
first_char: {
$in: ["0","1","2","3","4","5","6","7","8","9"]
}
}
}
])
Ответ 6
вы также можете попробовать следующее: использование регулярного выражения без использования $regex
db.zips.aggregate([
{$project : { city : { $substr : ["$city",0,1] } }},
{$sort : {city : 1}},
{$match: { city:/[0-9]/}}
])
Ответ 7
db.zips.aggregate([
{$project : {city:{$substr:["$city",0,1]},pop:1}},
{$group:{_id:"$city",sumPop:{$sum:"$pop"}}},
{$sort : {_id : 1}},
{$match:{_id : {$regex:/\d/}} },
{$group:{_id:"id",sumPop:{$sum:"$sumPop"}}},
]);