Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 4044: Search overhaul, part 1 #1840

Merged
merged 10 commits into from
Sep 15, 2014
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ gem 'resque_mailer'
gem 'resque-scheduler', :require => 'resque_scheduler'
#gem 'daemon-spawn', :require => 'daemon_spawn'
gem 'tire'
gem 'elasticsearch'
gem 'aws-sdk'
gem 'css_parser'

Expand Down
12 changes: 12 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ GEM
docile (1.1.1)
domain_name (0.5.12)
unf (>= 0.0.5, < 1.0.0)
elasticsearch (1.0.5)
elasticsearch-api (= 1.0.5)
elasticsearch-transport (= 1.0.5)
elasticsearch-api (1.0.5)
multi_json
elasticsearch-transport (1.0.5)
faraday
multi_json
email_spec (1.5.0)
launchy (~> 2.1)
mail (~> 2.2)
Expand All @@ -106,6 +114,8 @@ GEM
activesupport (>= 3.0.0)
faker (1.1.2)
i18n (~> 0.5)
faraday (0.9.0)
multipart-post (>= 1.2, < 3)
fastimage (1.4.0)
gherkin (2.12.0)
multi_json (~> 1.3)
Expand Down Expand Up @@ -149,6 +159,7 @@ GEM
mono_logger (1.1.0)
multi_json (1.10.0)
multi_xml (0.5.5)
multipart-post (2.0.0)
mysql2 (0.3.11)
mysql2 (0.3.11-x86-mingw32)
net-http-digest_auth (1.3)
Expand Down Expand Up @@ -350,6 +361,7 @@ DEPENDENCIES
cucumber-rails
database_cleaner
delorean
elasticsearch
email_spec
escape_utils
factory_girl
Expand Down
85 changes: 36 additions & 49 deletions app/models/external_work.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,55 +7,6 @@ class ExternalWork < ActiveRecord::Base
attr_protected :summary_sanitizer_version

has_many :related_works, :as => :parent

has_many :taggings, :as => :taggable, :dependent => :destroy
has_many :tags, :through => :taggings, :source => :tagger, :source_type => 'Tag'

has_many :filter_taggings, :as => :filterable, :dependent => :destroy
has_many :filters, :through => :filter_taggings

has_many :ratings,
:through => :taggings,
:source => :tagger,
:source_type => 'Tag',
:before_remove => :remove_filter_tagging,
:conditions => "tags.type = 'Rating'"
has_many :categories,
:through => :taggings,
:source => :tagger,
:source_type => 'Tag',
:before_remove => :remove_filter_tagging,
:conditions => "tags.type = 'Category'"
has_many :warnings,
:through => :taggings,
:source => :tagger,
:source_type => 'Tag',
:before_remove => :remove_filter_tagging,
:conditions => "tags.type = 'Warning'"
has_many :fandoms,
:through => :taggings,
:source => :tagger,
:source_type => 'Tag',
:before_remove => :remove_filter_tagging,
:conditions => "tags.type = 'Fandom'"
has_many :relationships,
:through => :taggings,
:source => :tagger,
:source_type => 'Tag',
:before_remove => :remove_filter_tagging,
:conditions => "tags.type = 'Relationship'"
has_many :characters,
:through => :taggings,
:source => :tagger,
:source_type => 'Tag',
:before_remove => :remove_filter_tagging,
:conditions => "tags.type = 'Character'"
has_many :freeforms,
:through => :taggings,
:source => :tagger,
:source_type => 'Tag',
:before_remove => :remove_filter_tagging,
:conditions => "tags.type = 'Freeform'"

belongs_to :language

Expand Down Expand Up @@ -189,4 +140,40 @@ def tag_groups
self.tags.group_by { |t| t.type.to_s }
end

######################
# SEARCH
######################

def bookmarkable_json
as_json(
root: false,
only: [
:title, :summary, :hidden_by_admin, :created_at, :language_id
],
methods: [
:posted, :restricted, :tag, :filter_ids, :rating_ids,
:warning_ids, :category_ids, :fandom_ids, :character_ids,
:relationship_ids, :freeform_ids, :creators, :revised_at
]
).merge(bookmarkable_type: "ExternalWork")
end

def posted
true
end
alias_method :posted?, :posted

def restricted
false
end
alias_method :restricted?, :restricted

def creators
[author]
end

def revised_at
created_at
end

end
74 changes: 74 additions & 0 deletions app/models/search/bookmark_indexer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
class BookmarkIndexer < Indexer

def self.klass
'Bookmark'
end

def self.index_all(options={})
options[:skip_delete] = true
BookmarkableIndexer.delete_index
BookmarkableIndexer.create_index
create_mapping
BookmarkedExternalWorkIndexer.index_all(skip_delete: true)
BookmarkedSeriesIndexer.index_all(skip_delete: true)
BookmarkedWorkIndexer.index_all(skip_delete: true)
super
end

def self.mapping
{
"bookmark" => {
"_parent" => {
type: 'bookmarkable'
},
properties: {
bookmarkable_type: {
type: 'string',
index: 'not_analyzed'
},
bookmarker: {
type: 'string',
analyzer: 'simple'
},
notes: {
type: 'string',
analyzer: 'snowball'
},
tag: {
type: 'string',
analyzer: 'simple'
}
}
}
}
end

####################
# INSTANCE METHODS
####################

# TODO: Make this work for deleted bookmarks
def routing_info(id)
{
'_index' => index_name,
'_type' => document_type,
'_id' => id,
'parent' => objects[id.to_i].bookmarkable_id
}
end

def document(object)
tags = object.tags
filters = tags.map{ |t| t.filter }.compact

object.as_json(
root: false,
except: [:notes_sanitizer_version, :delta],
methods: [:bookmarker, :collection_ids, :with_notes]
).merge(
tag: (tags + filters).map(&:name).uniq,
tag_ids: tags.map(&:id),
filter_ids: filters.map(&:id)
)
end
end
2 changes: 2 additions & 0 deletions app/models/search/bookmark_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class BookmarkQuery < Query
end
50 changes: 50 additions & 0 deletions app/models/search/bookmarkable_indexer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
class BookmarkableIndexer < Indexer

def self.index_name
"ao3_#{Rails.env}_bookmarks"
end

def self.document_type
'bookmarkable'
end

def self.mapping
{
'bookmarkable' => {
properties: {
title: {
type: 'string',
analyzer: 'simple'
},
creators: {
type: 'string',
analyzer: 'simple',
index_name: 'creator'
},
tag: {
type: 'string',
analyzer: 'simple'
},
work_types: {
type: 'string',
index: 'not_analyzed',
index_name: 'work_type'
}
}
}
}
end

def routing_info(id)
{
'_index' => index_name,
'_type' => document_type,
'_id' => "#{id}-#{klass.underscore}"
}
end

def document(object)
object.bookmarkable_json
end

end
5 changes: 5 additions & 0 deletions app/models/search/bookmarked_external_work_indexer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class BookmarkedExternalWorkIndexer < BookmarkableIndexer
def self.klass
"ExternalWork"
end
end
5 changes: 5 additions & 0 deletions app/models/search/bookmarked_series_indexer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class BookmarkedSeriesIndexer < BookmarkableIndexer
def self.klass
"Series"
end
end
10 changes: 10 additions & 0 deletions app/models/search/bookmarked_work_indexer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class BookmarkedWorkIndexer < BookmarkableIndexer
def self.klass
"Work"
end

# Only index works with bookmarks
def self.indexables
Work.joins(:stat_counter).where("bookmarks_count > 0")
end
end
Loading