ruby

четверг, 10 сентября 2009 г.

Полнотекстовый поиск в CouchDB, при использовании gem'a CouchRest

В CouchDB нет полнотекстового поиска по документам, то есть мы не можем искать неполные слова или часть значений.
Но это решается с помощью внешнего поискового движка lucene
под убунтой ставится примено так:

- ставим git и Maven2, для компиляции couchdb-lucene
# sudo apt-get install git-core maven2

- стягиваем репозиторий couchdb-lucene
# cd couchdb-lucene
# mvn

в итоге должен получиться jar-файл "couchdb-lucene*-jar-with-dependencies.jar" (вместо * ваша версия)

потом редактируем настройки couchdb (обычно это файл /usr/local/etc/couchdb/default.ini)
некоторые разделы уже созданы, а некоторые нужно добавить. проверяйте.



[couchdb]
os_process_timeout=60000 ; increase the timeout from 5 seconds.

[external]
fti=/usr/bin/java -server -jar /ПУТЬ_К_JAR_ФАЙЛУ/couchdb-lucene*-jar-with-dependencies.jar -search

[update_notification]
indexer=/usr/bin/java -server -jar /ПУТЬ_К_JAR_ФАЙЛУ/couchdb-lucene*-jar-with-dependencies.jar -index

[httpd_db_handlers]
_fti = {couch_httpd_external, handle_external_req, <<"fti">>}

А вот дальше идет западло, которое нигде не было описано.
- нужно открыть ваш CouchDB по адресу http://localhost:5984/_utils/
- войти в базу данных где хотите добавить поиск
- выбрать "Design documents"
- нажать "Create document ..."
- и назвать его "_design/lucene"
- добавить поле "fulltext"
- в котором писать условия поиска (какие параметры писать можно посмотреть тут), для примера сделаем поиск по полю subject и отдельно по полю body
{
   "by_subject": {
"defaults": {
"store": "yes"
},
"index": "function(doc) { var ret=new Document(); ret.add(doc.body); return ret }"
},
"by_body": {
"defaults": {
"store": "yes"
},
"index": "function(doc) { var ret=new Document(); ret.add(doc.body); return ret }"
}
}


все теперь если обратить по адресу
http://localhost:5984/ИМЯ_БАЗЫ/_fti/lucene/by_subj?q=Kill*
то нам найдет все темы которые начинаются с Kill

http://localhost:5984/ИМЯ_БАЗЫ/_fti/lucene/by_body?q=Kill*
то нам найдет все сообщения которые начинаются с Kill


Теперь добавляем поддержку в CouchRest
в своей модели добавьте метод (аля MonkeyPatch) и все.


def self.search(q)
CouchRest.get "http://localhost:5984/ИМЯ_БАЗЫ/_fti/lucene/by_word_solo?q=#{q}"
end

P.S.: если знаете способ красивее то предлагайте, а я расскажу всем.

понедельник, 7 сентября 2009 г.

Валидация в Ruby On Rails

https://wincent.com/wiki/Validating_passwords_with_Ruby_on_Rails


например

  MINIMUM_PASSPHRASE_LENGTH     = 8
MAXIMUM_PASSPHRASE_LENGTH = 64

validates_presence_of :passphrase,
:on => :create
validates_length_of :passphrase,
:in => MINIMUM_PASSPHRASE_LENGTH..MAXIMUM_PASSPHRASE_LENGTH,
:if => Proc.new { |u| !u.passphrase.blank? }
validates_confirmation_of :passphrase,
:if => Proc.new { |u| !u.passphrase.blank? }

воскресенье, 6 сентября 2009 г.

heredoc-строки в ruby

когда в переменную нужно записать длинный текст с переводом строки и не хочется записывать в одну строку типа
text = "Grocery list\n------------\n1. Salad\n2. Strawberries"

то можно использовать конструкцию heredoc
для Руби синтаксис такой:
puts <<GROCERY_LIST
Grocery list
------------
1. Salad mix.
2. Strawberries.*
3. Cereal.
4. Milk.*

* Organic
GROCERY_LIST

список всех изменений в Ruby 1.9

http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9

суббота, 5 сентября 2009 г.

Список главных отличий Ruby 1.8.6 от Ruby 1.9

http://slideshow.rubyforge.org/ruby19.html
навигация по слайдам стрелками

Создаем новый класс Hello

class Hello
def initialize
@msg = "Hello"
end
def msg
@msg
end
def msg=(m)
@msg = m
end
def say
puts @msq
end
end

h = Hello.new
puts h.msg # prints "Hello"
h.msg = "Hi"
puts h.msg # prints "Hi"
h.say # prints "Hi"

Печатаем таблица умножения

(1..10).each do |x|
(1..10).each do |y|
printf "%5d", x*y
end
puts
end