#mongodb #scala #scala-2.9
#mongodb #scala #scala-2.9
Вопрос:
У меня есть существующее приложение Scala, и оно использует классы case, которые затем сохраняются в MongoDB. Мне нужно ввести новое поле в класс case, но его значение является производным от существующего поля.
Например, есть номер телефона, и я хочу добавить нормализованный номер телефона, сохранив исходный номер телефона. Я обновлю существующие записи в MongoDB, но мне нужно будет добавить эту функцию нормализации в существующий код сохранения и обновления.
Итак, есть ли в Scala какой-нибудь удобный ярлык для добавления «привязки» к определенному полю класса case? Например, в Java можно изменить установщик номера телефона.
Редактировать:
Решение в ответе Кристиана отлично работает само по себе, но в моем случае у меня есть значения по умолчанию для полей (я думаю, из-за Намаза …)
case class Person(name: String = "a", phone: Option[String] = None, normalizedPhone: Option[String] = None)
object Person {
def apply(name: String, phone: Option[String]): Person = Person(name, phone, Some("xxx" phone.getOrElse("")))
}
И если использовать что-то вроде:
Person(phone = Some("s"))
Я получу: Person = Person(a,Some(s),None)
Ответ №1:
Вы можете определить метод apply в сопутствующем объекте:
case class Person(name: String, phone: String, normalizedPhone: String)
object Person {
def apply(name: String, phone: String): Person = Person(name, phone, "xxx" phone)
}
Затем в repl:
scala> Person("name", "phone")
res3: Person = Person(name,phone,xxxphone)
Комментарии:
1. Это отвечает на мой первоначальный вопрос. В итоге я выбрал совершенно другое решение, нормализовав поле на месте и вообще не вводя новое.
Ответ №2:
Вы можете добавить методы к классу case, которые будут содержать логику преобразования из существующих полей. Например:
case class Person(name: String, phone: String) {
def normalizedPhone = " 40" phone
}
Затем вы можете использовать метод так же, как если бы это было поле:
val p1 = new Person("Joe", "7234")
println(p1.normalizedPhone) // 407234
Комментарии:
1. В моем случае я думаю, что мне нужно иметь его как отдельное поле, чтобы сохранить его в MongoDB.
2. Но зачем сохранять его, если оно всегда является производным от другого поля? Разве это не было бы избыточностью?
3. Оно должно быть в БД, чтобы его можно было быстро индексировать и запрашивать. Запрос регулярных выражений MongoDB был недостаточно быстрым.
Ответ №3:
Я думаю, что это близко к тому, что вам нужно. Поскольку вы не можете переопределить сгенерированный мутатор, добавьте к существующему полю префикс подчеркивания, сделайте его закрытым, а затем напишите методы доступа и мутатора для исходного имени поля. После этого вам понадобится только дополнительная строка в конструкторе для размещения инициализации поля на основе конструктора.
case class Test(private var _phoneNumber: String, var formatted: String = "") {
phoneNumber_=(_phoneNumber)
def phoneNumber = _phoneNumber
def phoneNumber_=(phoneNumber: String) {
_phoneNumber = phoneNumber
formatted = "formatted" phoneNumber
}
}
object Test {
def main(args: Array[String]) {
var t = Test("09048751234")
println(t.phoneNumber)
println(t.formatted)
t.phoneNumber = "08068745963"
println(t.phoneNumber)
println(t.formatted)
}
}