lexster 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +58 -0
- data/Gemfile +4 -0
- data/LICENSE +19 -0
- data/README.md +467 -0
- data/Rakefile +7 -0
- data/TODO.md +4 -0
- data/lexster.gemspec +28 -0
- data/lib/lexster.rb +239 -0
- data/lib/lexster/batch.rb +168 -0
- data/lib/lexster/config.rb +6 -0
- data/lib/lexster/database_cleaner.rb +12 -0
- data/lib/lexster/middleware.rb +16 -0
- data/lib/lexster/model_additions.rb +121 -0
- data/lib/lexster/model_config.rb +57 -0
- data/lib/lexster/node.rb +210 -0
- data/lib/lexster/railtie.rb +15 -0
- data/lib/lexster/relationship.rb +163 -0
- data/lib/lexster/search_session.rb +28 -0
- data/lib/lexster/version.rb +3 -0
- data/spec/lexster/batch_spec.rb +170 -0
- data/spec/lexster/config_spec.rb +13 -0
- data/spec/lexster/model_config_spec.rb +24 -0
- data/spec/lexster/node_spec.rb +131 -0
- data/spec/lexster/relationship_spec.rb +102 -0
- data/spec/lexster/search_spec.rb +117 -0
- data/spec/lexster_spec.rb +11 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/support/database.yml +6 -0
- data/spec/support/models.rb +106 -0
- data/spec/support/schema.rb +44 -0
- metadata +172 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Lexster::ModelAdditions do
|
4
|
+
context "search" do
|
5
|
+
let(:index_name) { "articles_search_index_#{Time.now.to_f.to_s.gsub('.', '')}" }
|
6
|
+
|
7
|
+
it "should index and find node in fulltext" do
|
8
|
+
Lexster.db.create_node_index(index_name, "fulltext", "lucene")
|
9
|
+
|
10
|
+
n = Neography::Node.create(name: "test hello world", year: 2012)
|
11
|
+
Lexster.db.add_node_to_index(index_name, "name", n.name, n)
|
12
|
+
Lexster.db.add_node_to_index(index_name, "year", n.year, n)
|
13
|
+
|
14
|
+
[
|
15
|
+
"name:test",
|
16
|
+
"year:2012",
|
17
|
+
"name:test AND year:2012"
|
18
|
+
].each { |q|
|
19
|
+
results = Lexster.db.find_node_index(index_name, q)
|
20
|
+
results.length.should == 1
|
21
|
+
Lexster.db.send(:get_id, results).should == n.neo_id
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should index item on save" do
|
26
|
+
r = rand(1000000)
|
27
|
+
article = Article.create!(title: "Hello world #{r}", body: "Lorem ipsum dolor sit amet", year: r)
|
28
|
+
|
29
|
+
[
|
30
|
+
"title:#{r}",
|
31
|
+
"year:#{r}",
|
32
|
+
"title:#{r} AND year:#{r}"
|
33
|
+
].each do |q|
|
34
|
+
results = Lexster.db.find_node_index(Lexster::DEFAULT_FULLTEXT_SEARCH_INDEX_NAME, q)
|
35
|
+
|
36
|
+
results.should_not be_nil
|
37
|
+
results.length.should == 1
|
38
|
+
Lexster.db.send(:get_id, results).should == article.neo_node.neo_id
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "search session" do
|
43
|
+
it "should return a search session" do
|
44
|
+
Article.neo_search("hello").should be_a(Lexster::SearchSession)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should find hits" do
|
48
|
+
article = Article.create!(title: "Hello world", body: "Lorem ipsum dolor sit amet", year: 2012)
|
49
|
+
|
50
|
+
Article.neo_search("hello").hits.should == [ article.neo_node ]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should find results with a search string" do
|
54
|
+
article = Article.create!(title: "Hello world", body: "Lorem ipsum dolor sit amet", year: 2012)
|
55
|
+
|
56
|
+
Article.neo_search("hello").results.should == [ article ]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should find results with a hash" do
|
60
|
+
articles = [
|
61
|
+
Article.create!(title: "How to draw manga", body: "Lorem ipsum dolor sit amet", year: 2012),
|
62
|
+
Article.create!(title: "Manga x", body: "Lorem ipsum dolor sit amet", year: 2013)
|
63
|
+
]
|
64
|
+
|
65
|
+
|
66
|
+
Article.neo_search(year: 2012).results.should == [ articles[0] ]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "search in multiple types" do
|
71
|
+
before :each do
|
72
|
+
@articles = [
|
73
|
+
Article.create!(title: "How to draw manga", body: "Lorem ipsum dolor sit amet", year: 2012),
|
74
|
+
Article.create!(title: "Manga x", body: "Lorem ipsum dolor sit amet", year: 2012)
|
75
|
+
]
|
76
|
+
|
77
|
+
@movies = [
|
78
|
+
Movie.create!(name: "Anime is not Manga", slug: "anime")
|
79
|
+
]
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should search in multiple types" do
|
83
|
+
Lexster.search([Article, Movie], "manga").results.should =~ @articles + @movies
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should search in single type when specified" do
|
87
|
+
Lexster.search([Article], "manga").results.should =~ @articles
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "search matching types" do
|
92
|
+
before :each do
|
93
|
+
@articles = [
|
94
|
+
Article.create!(title: "Comics: How to draw manga", body: "Lorem ipsum dolor sit amet", year: 2012),
|
95
|
+
Article.create!(title: "Manga x", body: "Lorem ipsum dolor sit amet", year: 2012),
|
96
|
+
Article.create!(title: "hidden secrets of comics masters", body: "Lorem ipsum dolor sit amet", year: 2012),
|
97
|
+
Article.create!(title: "hidden secrets of manga comics artists", body: "Lorem ipsum dolor sit amet", year: 2012)
|
98
|
+
]
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should return search results only matches with AND" do
|
102
|
+
Lexster.search([Article],"manga comics").results.size.should eq(1)
|
103
|
+
|
104
|
+
Lexster.search([Article],"manga comics",{match_type: "AND"}).results.size.should eq(1)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should return search results all results with OR" do
|
108
|
+
Lexster.search([Article],"manga comics",{match_type: "OR"}).results.size.should eq(4)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should fail with wrong match_type" do
|
112
|
+
expect {Lexster.search([Article],"manga comics",{match_type: "MAYBE"})}.to raise_error("Invalid match_type option. Valid values are AND,OR")
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'lexster'
|
2
|
+
require 'active_record'
|
3
|
+
require 'neography'
|
4
|
+
require 'rest-client'
|
5
|
+
|
6
|
+
# ENV['NEOID_LOG'] = 'true'
|
7
|
+
|
8
|
+
uri = URI.parse(ENV["NEO4J_URL"] ? ENV["NEO4J_URL"] : ENV['TRAVIS'] ? "http://localhost:7474" : "http://localhost:7574")
|
9
|
+
$neo = Neography::Rest.new(uri.to_s)
|
10
|
+
|
11
|
+
Neography.configure do |c|
|
12
|
+
c.server = uri.host
|
13
|
+
c.port = uri.port
|
14
|
+
|
15
|
+
if uri.user && uri.password
|
16
|
+
c.authentication = 'basic'
|
17
|
+
c.username = uri.user
|
18
|
+
c.password = uri.password
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Lexster.db = $neo
|
23
|
+
|
24
|
+
logger, ActiveRecord::Base.logger = ActiveRecord::Base.logger, Logger.new('/dev/null')
|
25
|
+
ActiveRecord::Base.configurations = YAML::load(IO.read(File.join(File.dirname(__FILE__), 'support/database.yml')))
|
26
|
+
ActiveRecord::Base.establish_connection('sqlite3')
|
27
|
+
|
28
|
+
require 'support/schema'
|
29
|
+
require 'support/models'
|
30
|
+
|
31
|
+
ActiveRecord::Base.logger = logger
|
32
|
+
|
33
|
+
RSpec.configure do |config|
|
34
|
+
config.mock_with :rspec
|
35
|
+
|
36
|
+
config.before(:all) do
|
37
|
+
end
|
38
|
+
|
39
|
+
config.before(:each) do
|
40
|
+
Lexster.node_models.each(&:destroy_all)
|
41
|
+
Lexster.clean_db(:yes_i_am_sure)
|
42
|
+
Lexster.reset_cached_variables
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
Lexster.initialize_all
|
@@ -0,0 +1,106 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
include ActiveModel::Validations::Callbacks
|
3
|
+
|
4
|
+
has_many :likes
|
5
|
+
has_many :movies, through: :likes
|
6
|
+
|
7
|
+
has_many :user_follows
|
8
|
+
|
9
|
+
def likes?(movie)
|
10
|
+
likes.where(movie_id: movie.id).exists?
|
11
|
+
end
|
12
|
+
|
13
|
+
def like!(movie)
|
14
|
+
movies << movie unless likes?(movie)
|
15
|
+
likes.where(movie_id: movie.id).first
|
16
|
+
end
|
17
|
+
|
18
|
+
def unlike!(movie)
|
19
|
+
likes.where(movie_id: movie.id, user_id: self.id).destroy_all
|
20
|
+
end
|
21
|
+
|
22
|
+
include Lexster::Node
|
23
|
+
|
24
|
+
lexsterable do |c|
|
25
|
+
c.field :name
|
26
|
+
c.field :slug
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Movie < ActiveRecord::Base
|
31
|
+
include ActiveModel::Validations::Callbacks
|
32
|
+
|
33
|
+
has_many :likes
|
34
|
+
has_many :users, through: :likes
|
35
|
+
|
36
|
+
include Lexster::Node
|
37
|
+
|
38
|
+
lexsterable do |c|
|
39
|
+
c.field :name
|
40
|
+
c.field :slug
|
41
|
+
c.field :year
|
42
|
+
|
43
|
+
c.search do |s|
|
44
|
+
s.fulltext :name
|
45
|
+
|
46
|
+
s.index :name
|
47
|
+
s.index :slug
|
48
|
+
s.index :year
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class UserFollow < ActiveRecord::Base
|
54
|
+
include ActiveModel::Validations::Callbacks
|
55
|
+
|
56
|
+
belongs_to :user
|
57
|
+
belongs_to :item, polymorphic: true
|
58
|
+
|
59
|
+
include Lexster::Relationship
|
60
|
+
|
61
|
+
lexsterable do |c|
|
62
|
+
c.relationship start_node: :user, end_node: :item, type: :follows
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Like < ActiveRecord::Base
|
67
|
+
include ActiveModel::Validations::Callbacks
|
68
|
+
|
69
|
+
belongs_to :user
|
70
|
+
belongs_to :movie
|
71
|
+
|
72
|
+
include Lexster::Relationship
|
73
|
+
|
74
|
+
lexsterable do |c|
|
75
|
+
c.relationship start_node: :user, end_node: :movie, type: :likes
|
76
|
+
c.field :rate
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class Article < ActiveRecord::Base
|
81
|
+
include ActiveModel::Validations::Callbacks
|
82
|
+
include Lexster::Node
|
83
|
+
lexsterable do |c|
|
84
|
+
c.field :title
|
85
|
+
c.field :year
|
86
|
+
c.field :title_length do
|
87
|
+
self.title ? self.title.length : 0
|
88
|
+
end
|
89
|
+
|
90
|
+
c.search do |s|
|
91
|
+
s.fulltext :title
|
92
|
+
|
93
|
+
s.index :title
|
94
|
+
s.index :body
|
95
|
+
s.index :year
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class NoAutoIndexNode < ActiveRecord::Base
|
101
|
+
include ActiveModel::Validations::Callbacks
|
102
|
+
include Lexster::Node
|
103
|
+
lexsterable auto_index: false do |c|
|
104
|
+
c.field :name
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
ActiveRecord::Schema.define :version => 0 do
|
2
|
+
create_table :users do |t|
|
3
|
+
t.string :name
|
4
|
+
t.string :slug
|
5
|
+
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
|
9
|
+
create_table :movies do |t|
|
10
|
+
t.string :name
|
11
|
+
t.string :slug
|
12
|
+
t.integer :year
|
13
|
+
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
|
17
|
+
create_table :likes do |t|
|
18
|
+
t.integer :user_id
|
19
|
+
t.integer :movie_id
|
20
|
+
t.integer :rate
|
21
|
+
|
22
|
+
t.timestamps
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
create_table :articles do |t|
|
27
|
+
t.string :title
|
28
|
+
t.string :body
|
29
|
+
t.integer :year
|
30
|
+
|
31
|
+
t.timestamps
|
32
|
+
end
|
33
|
+
|
34
|
+
create_table :user_follows do |t|
|
35
|
+
t.belongs_to :user
|
36
|
+
t.belongs_to :item, polymorphic: true
|
37
|
+
|
38
|
+
t.timestamps
|
39
|
+
end
|
40
|
+
|
41
|
+
create_table :no_auto_index_nodes do |t|
|
42
|
+
t.string :name
|
43
|
+
end
|
44
|
+
end
|
metadata
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lexster
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nelson Wittwer, Elad Ossadon
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rest-client
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activerecord
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: neography
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Extend Ruby on Rails ActiveRecord with Titan nodes. Keep RDBMS and utilize
|
98
|
+
the power of Gremlin queries. Fork of Neoid.
|
99
|
+
email:
|
100
|
+
- nelsonwittwer@gmail.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- .gitignore
|
106
|
+
- .rspec
|
107
|
+
- .travis.yml
|
108
|
+
- CHANGELOG.md
|
109
|
+
- Gemfile
|
110
|
+
- LICENSE
|
111
|
+
- README.md
|
112
|
+
- Rakefile
|
113
|
+
- TODO.md
|
114
|
+
- lexster.gemspec
|
115
|
+
- lib/lexster.rb
|
116
|
+
- lib/lexster/batch.rb
|
117
|
+
- lib/lexster/config.rb
|
118
|
+
- lib/lexster/database_cleaner.rb
|
119
|
+
- lib/lexster/middleware.rb
|
120
|
+
- lib/lexster/model_additions.rb
|
121
|
+
- lib/lexster/model_config.rb
|
122
|
+
- lib/lexster/node.rb
|
123
|
+
- lib/lexster/railtie.rb
|
124
|
+
- lib/lexster/relationship.rb
|
125
|
+
- lib/lexster/search_session.rb
|
126
|
+
- lib/lexster/version.rb
|
127
|
+
- spec/lexster/batch_spec.rb
|
128
|
+
- spec/lexster/config_spec.rb
|
129
|
+
- spec/lexster/model_config_spec.rb
|
130
|
+
- spec/lexster/node_spec.rb
|
131
|
+
- spec/lexster/relationship_spec.rb
|
132
|
+
- spec/lexster/search_spec.rb
|
133
|
+
- spec/lexster_spec.rb
|
134
|
+
- spec/spec_helper.rb
|
135
|
+
- spec/support/database.yml
|
136
|
+
- spec/support/models.rb
|
137
|
+
- spec/support/schema.rb
|
138
|
+
homepage: ''
|
139
|
+
licenses: []
|
140
|
+
metadata: {}
|
141
|
+
post_install_message:
|
142
|
+
rdoc_options: []
|
143
|
+
require_paths:
|
144
|
+
- lib
|
145
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - '>='
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
155
|
+
requirements: []
|
156
|
+
rubyforge_project: lexster
|
157
|
+
rubygems_version: 2.1.9
|
158
|
+
signing_key:
|
159
|
+
specification_version: 4
|
160
|
+
summary: Titan for ActiveRecord
|
161
|
+
test_files:
|
162
|
+
- spec/lexster/batch_spec.rb
|
163
|
+
- spec/lexster/config_spec.rb
|
164
|
+
- spec/lexster/model_config_spec.rb
|
165
|
+
- spec/lexster/node_spec.rb
|
166
|
+
- spec/lexster/relationship_spec.rb
|
167
|
+
- spec/lexster/search_spec.rb
|
168
|
+
- spec/lexster_spec.rb
|
169
|
+
- spec/spec_helper.rb
|
170
|
+
- spec/support/database.yml
|
171
|
+
- spec/support/models.rb
|
172
|
+
- spec/support/schema.rb
|