it is my first time to use elasticsearch Grails plugin in my Grails2.5.1application , when i'm trying to search for age=35 using elasticSearchService.search("${age:35}").searchResults or using domainName.search("${age:35}").searchResults the searchresults is empty although there is a record in the DB age is equal to 35. And is there any useful tutorial for using ElasticSearch with Grails.
here is my domain:
class EmploymentSeeker {
String empType
String email
String fullName
String expYears
String socialStatus
Integer nubOfKids =0
String computerKnowledge
String militaryStatus
String haveDrivingLic
String gender
String eduQualification
String hasVehicle
String placeOfStudying
String courses
String currentTitle
String currentEmployerName
Integer age
Date dateCreated
static searchable = {
age boost:2.0
root true
except = ['email', 'fullName', 'placeOfStudying', 'currentTitle', 'currentEmployerName', 'dateCreated']
}
static constraints = {
}
static mapping={
}
}
Looks like you have a rogue '$' in your query string. It probably should be:
elasticSearchService.search("age:35")
${..} is needed only if you are passing in a query and want Groovy to replace the expression before invoking the ElasticSearchService.
Related
How can I get a list of field names for a domain class that are not nullable?
For instance, in the following domain:
class MyDomain {
String field1
String field2
String field3
String field4
static constraints = {
field2 nullable: true
field3 nullable: true
}
}
How can I get back the list ['field1','field4'] in a controller?
I'm validating rows in a CSV, and some of the row information is different from what is stored in the domain, so it would be preferable to get a List of String names rather than bind to a command object with exclusions.
You can use the constrainedProperties. It gives all the constraints of the particular domain class.
And now you want only the non-nullble constraints then filter out the result for it.
Example :
MyDomain.constrainedProperties.findResults { it.value.nullable ? null : it.key }
Output :
['field1','field4']
For grails 2.x users :
MyDomain.getConstraints().findResults { it.value.nullable ? null : it.key }
You need to use the PersistentEntity API
Set<String> propertyNames = [] as Set
for (PersistentProperty prop: MyDomain.gormPersistentEntity.persistentProperties) {
if (!prop.mapping.mappedForm.nullable) {
propertyNames.add(prop.name)
}
}
You may have to exclude things like version or timestamp properties depending on what you want.
I am receiving the following errors in my "Class" class in Grails. For each field, it is telling me that I have a duplicate field. Which doesn't make any sense, because all I'm trying to do is map the fields with their associated table columns. The class fields and the fields in my mapping closure are all underlined. Here is my class so far:
package booklist
class Class {
Integer id
String name
String description
String instructor
String courseNumber
String lineNumber
List books
BigDecimal bookTotalPrice
String sequenceNumber
String subjectCode
static constraints = {
}
static mapping = {
//Uses the default datasource
table ''
columns {
id column: 'class_id'
name column: 'class_name'
description column: 'course_description'
instructor column: 'instructor_name'
courseNumber column: 'course_number'
lineNumber column: 'line_number'
bookTotalPrice column: 'book_total_price'
sequenceNumber column: 'sequence_number'
subjectCode column: 'subject_code'
}
}
}
You don't need to declared in static mapping the fields that you don't need to rename. Just write this:
package booklist
class MyClass {
Integer id
String name
String description
String instructor
String courseNumber
String lineNumber
List books
BigDecimal bookTotalPrice
String sequenceNumber
String subjectCode
static mapping = {
description column: 'course_description'
}
}
Grails works with the CoC (Convention Over Configuration) approach: if you don't need to change something, don't write it and a convention will be used.
For more details about the column mapping, take a look at the Grails documentation: http://grails.org/doc/latest/ref/Database%20Mapping/column.html
I have a domain class DefectData as follows
class DefectData {
String taskId
String defectId
String defectSummary
String severity
String phaseDetected
String rejected
String loggedBy
String howFound
Date dateFound
String defectType
String defectCause
ProgressData progressData
def DefectData(){}
static constraints = {
id generator:"assigned",name:"defectId"
}
static belongsTo=[taskId:ProgressData]
static namedQueries={
getDefectDataByYearMonth{int month,int year ->
def plannedDate=Date.parse("mm-yy","${month} - ${year}")
}
}
}
I am trying this sort of query, which would enable me to get the count of the defects of which were detected in the "Testing" phase.
def testingDefects(int month,int year){
countTestingDefects=DefectData.getDefectDataByYearMonth(month,year).findAllWhere(phaseDetected:"Testing").count()
println countTestingDefects
}
Though, I am getting this error, that the date is unparseable
testingDefects(03,2012)
Unparsable date "3-12". I just want to list the records on the basis of the month and the year.
What could be the issue?
Just throw away your spaces
def (month,year) = [2,2012]
Date.parse("mm-yy","${month}-${year}")
works for me
Give a try to Joda-Time if you need more control and ease about date parsing
Is it possible to both validate, that the provided data is in the form of a phone number AND trim it down to just the numbers in the validator?
Input: (902) 837-2832
Output: VALID: YES, 9028372832
Or do I have to convert the input to the number-only format after the fact?
Add a property to your model with only a getter that returns the stripped down version of the property that is bound to the input. Put your validation attribute on that property.
public string PhoneNumber {get;set;}
[Required(ErrorMessage="Phone number is required.")]
[RegularExpression(#"\d{10}", ErrorMessage="Phone number is invalid.")]
public string PhoneNumberValue
{
get
{
var temp = PhoneNumber
temp = Regex.Replace(temp, #"[^0-9]", "");
temp = temp.Length == 11 && temp.StartsWith("1")
? temp.Substring(1) : temp;
}
set
{
// I can't remember off the top of my head if MVC model
// binding requires a setter or not. If so, just leave this
// empty. Otherwise you can remove it entirely.
}
}
Then, in your view, just render the alternate validation message.
#Html.LabelFor(x=>x.PhoneNumber)
#Html.TextBoxFor(x=>x.PhoneNumber)
#Html.ValidationMessageFor(x=>x.PhoneNumberValue)
Here is an example how to validate with Regular expression:
[Required(ErrorMessage="Phone Number is required")]
[RegularExpression("^(?([0-9]{3}))?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$", ErrorMessage="Not a valid number")]
public string PhoneNumber { get; set; }
We may use Trim method of string to clean the phone number and get only digits.
char[] charsToTrim = { '(', ' ', ')', '-'};
string phoneNumber = "(123)-345-6789";
string result = banner.Trim(charsToTrim);
Finally here is a post that explains Enabling Validation using DataAnnotations in more detail
I am new to Grails. I have a Person domain class as :
class Person {
String firstName
String lastName
String gender
Date dateOfBirth
}
And wondering if I can define possible values for a property - say gender as {M, F, U} so that these three values will be listed in combo box when using dynamic scaffolding for Person controller.
Here I just wanted to know if there is such feature in Grails framework? If such feature exists , then how can I use it?
From the documentation http://grails.org/doc/latest/guide/scaffolding.html, you should be able to use an inList constraint:
class Person {
String firstName
String lastName
String gender
Date dateOfBirth
def constraints = {
gender( inList: ["M", "F", "U"])
}
}
This should scaffold to a select list for the gender field, depending on the version of Grails you're using. 2.0+ definitely does this.
Here is an alternative solution
class Person {
String firstName
String lastName
enum Gender {
M(1),
F(2),
U(3)
private Gender(int val) { this.id = val }
final int id
}
Gender gender = Gender.U
Date dateOfBirth
def constraints = {
gender()
}
}
This will store gender in the database as an integer (1,2,3) and default the gender to U. The benefit here is you can rename what F, M, and U mean without handling a data migration.