Skip to content

Commit

Permalink
added the first custom implementation of search
Browse files Browse the repository at this point in the history
  • Loading branch information
jettro committed Dec 16, 2009
1 parent 3422b61 commit 4de38e5
Show file tree
Hide file tree
Showing 7 changed files with 273 additions and 1 deletion.
168 changes: 168 additions & 0 deletions grails-app/conf/Searchable.groovy
@@ -0,0 +1,168 @@
/**
* This {@link groovy.util.ConfigObject} script provides Grails Searchable Plugin configuration.
*
* You can use the "environments" section at the end of the file to define per-environment
* configuration.
*
* Note it is NOT required to add a reference to this file in Config.groovy; it is loaded by
* the plugin itself.
*
* Available properties in the binding are:
*
* @param userHome The current user's home directory.
* Same as System.properties['user.home']
* @param appName The Grails environment (ie, "development", "test", "production").
* Same as System.properties['grails.env']
* @param appVersion The version of your application
* @param grailsEnv The Grails environment (ie, "development", "test", "production").
* Same as System.properties['grails.env']
*
* You can also use System.properties to refer to other JVM properties.
*
* This file is created by "grails install-searchable-config", and replaces
* the previous "SearchableConfiguration.groovy"
*/
searchable {

/**
* The location of the Compass index
*
* Examples: "/home/app/compassindex", "ram://app-index" or null to use the default
*
* The default is "${user.home}/.grails/projects/${app.name}/searchable-index/${grails.env}"
*/
compassConnection = new File(
"${userHome}/.grails/projects/${appName}/searchable-index/${grailsEnv}"
).absolutePath

/**
* Any settings you wish to pass to Compass
*
* Use this to configure custom/override default analyzers, query parsers, eg
*
* Map compassSettings = [
* 'compass.engine.analyzer.german.type': 'German'
* ]
*
* gives you an analyzer called "german" you can then use in mappings and queries, like
*
* class Book {
* static searchable = { content analyzer: 'german' }
* String content
* }
*
* Book.search("unter", analyzer: 'german')
*
* Documentation for Compass settings is here: http://www.compass-project.org/docs/2.1.0M2/reference/html/core-settings.html
*/
compassSettings = [:]

/**
* Default mapping property exclusions
*
* No properties matching the given names will be mapped by default
* ie, when using "searchable = true"
*
* This does not apply for classes using "searchable = [only/except: [...]]"
* or mapping by closure
*/
defaultExcludedProperties = ["password"]

/**
* Default property formats
*
* Value is a Map between Class and format string, eg
*
* [(Date): "yyyy-MM-dd'T'HH:mm:ss"]
*
* Only applies to class properties mapped as "searchable properties", which are typically
* simple class types that can be represented as Strings (rather than references
* or components) AND only required if overriding the built-in format.
*/
defaultFormats = [:]

/**
* Set default options for each SearchableService/Domain-class method, by method name.
*
* These can be overriden on a per-query basis by passing the method a Map of options
* containing those you want to override.
*
* You may want to customise the options used by the search method, which are:
*
* @param reload whether to reload domain class instances from the DB: true|false
* If true, the search will be slower but objects will be associated
* with the current Hibernate session
* @param escape whether to escape special characters in string queries: true|false
* @param offset the 0-based hit offset of the first page of results.
* Normally you wouldn't change it from 0, it's only here because paging
* works by using an offset + max combo for a specific page
* @param max the page size, for paged search results
* @param defaultOperator if the query does not otherwise indicate, then the default operator
* applied: "or" or "and".
* If "and" means all terms are required for a match, if "or" means
* any term is required for a match
* @param suggestQuery if true and search method is returning a search-result object
* (rather than a domain class instance, list or count) then a
* "suggestedQuery" property is also added to the search-result.
* This can also be a Map of options as supported by the suggestQuery
* method itself
*
* For the options supported by other methods, please see the documentation
* http://grails.org/Searchable+Plugin
*/
defaultMethodOptions = [
search: [reload: false, escape: false, offset: 0, max: 10, defaultOperator: "and"],
suggestQuery: [userFriendly: true]
]

/**
* Should changes made through GORM/Hibernate be mirrored to the index
* automatically (using Compass::GPS)?
*
* If false, you must manage the index manually using index/unindex/reindex
*/
mirrorChanges = true

/**
* Should the database be indexed at startup (using Compass:GPS)?
*
* Possible values: true|false|"fork"
*
* The value may be a boolean true|false or a string "fork", which means true,
* and fork a thread for it
*
* If you use BootStrap.groovy to insert your data then you should use "true",
* which means do a non-forking, otherwise "fork" is recommended
*/
bulkIndexOnStartup = true

/**
* Should index locks be removed (if present) at startup?
*/
releaseLocksOnStartup = true
}

// per-environment settings
environments {
development {
searchable {
// development is default; inherits from above
}
}

test {
searchable {
// disable bulk index on startup
bulkIndexOnStartup = false

// use faster in-memory index
compassConnection = "ram://test-index"
}
}

production {
searchable {
// add your production settings here
}
}
}
33 changes: 33 additions & 0 deletions grails-app/controllers/SearchController.groovy
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2009. Gridshore
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

class SearchController {

def search = {
def query = params.q

if (!query) {
return [:]
}

try {
def searchResult = Comment.search (query,params)
return [searchResult:searchResult]
} catch (e) {
return [searchError:true]
}
}
}
5 changes: 4 additions & 1 deletion grails-app/domain/Comment.groovy
Expand Up @@ -18,5 +18,8 @@ class Comment {
content(blank:false, widget:"textarea") content(blank:false, widget:"textarea")
} }


static searchable = true static searchable = {
only = ['content','name']
spellCheck "include"
}
} }
1 change: 1 addition & 0 deletions grails-app/views/overview/index.gsp
Expand Up @@ -18,6 +18,7 @@
<span class="menuButton"><g:link controller="environment">Environments</g:link></span> <span class="menuButton"><g:link controller="environment">Environments</g:link></span>
<span class="menuButton"><g:link controller="server">Servers</g:link></span> <span class="menuButton"><g:link controller="server">Servers</g:link></span>
<span class="menuButton"><g:link controller="vlan">Vlans</g:link></span> <span class="menuButton"><g:link controller="vlan">Vlans</g:link></span>
<span class="menuButton"><g:link controller="search">Search</g:link></span>
</div> </div>
<g:each in="${environments}" var="environment"> <g:each in="${environments}" var="environment">
<div class="yui-ge environment"> <div class="yui-ge environment">
Expand Down
47 changes: 47 additions & 0 deletions grails-app/views/search/search.gsp
@@ -0,0 +1,47 @@
%{--
- Copyright (c) 2009. Gridshore
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--}%

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>Search comments</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="layout" content="main"/>

</head>
<body>
<div class="nav">
<span class="menuButton"><a class="home" href="${resource(dir: '')}">Home</a></span>
<span class="menuButton"><g:link controller="environment">Environments</g:link></span>
<span class="menuButton"><g:link controller="server">Servers</g:link></span>
<span class="menuButton"><g:link controller="vlan">Vlans</g:link></span>
<span class="menuButton"><g:link controller="search">Search</g:link></span>
</div>
<g:form>
<g:textField name="q" value="${params.q}"/>
<g:submitButton name="Search" value="Search"/>
</g:form>

<g:if test="${searchResult?.results}">
<g:each var="result" in="${searchResult.results}">
<div class="searchComment">
<g:link controller="comment" action="show" id="${result.id}">${result.name}</g:link><br/>
${result.content}
</div>
</g:each>
</g:if>
</body>
</html>
15 changes: 15 additions & 0 deletions test/unit/SearchControllerTests.groovy
@@ -0,0 +1,15 @@
import grails.test.*

class SearchControllerTests extends ControllerUnitTestCase {
protected void setUp() {
super.setUp()
}

protected void tearDown() {
super.tearDown()
}

void testSomething() {

}
}
5 changes: 5 additions & 0 deletions web-app/css/main.css
Expand Up @@ -80,6 +80,11 @@ div.flash {
background-color: lightgreen; background-color: lightgreen;
color:black; color:black;
} }

.searchComment {
border: 1px solid lightskyblue;
margin-bottom:10px;
}
/* GENERAL */ /* GENERAL */


.spinner { .spinner {
Expand Down

0 comments on commit 4de38e5

Please sign in to comment.