From aaf800f04bce2e29a273d234e94eb93f46d2a1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:18:07 +0200 Subject: [PATCH 01/67] Mongoid 7 compatibility --- .travis.yml | 5 +++-- Gemfile | 4 +++- lib/mongoid/full_text_search.rb | 14 +++++++------- mongoid_fulltext.gemspec | 2 +- spec/mongoid/full_text_search_spec.rb | 2 +- spec/spec_helper.rb | 2 +- spec/support/mongoid.rb | 2 +- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8d3c306..8e48b6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,12 @@ sudo: false matrix: include: + - rvm: 2.5.0 + env: + - MONGOID_VERSION=7.0 - rvm: 2.3.1 env: - MONGOID_VERSION=6.0 - before_script: - - bundle exec danger - rvm: 2.3.1 env: - MONGOID_VERSION=5.0 diff --git a/Gemfile b/Gemfile index 01dcc47..1a8278b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,8 @@ source 'http://rubygems.org' -case version = ENV['MONGOID_VERSION'] || '6' +case version = ENV['MONGOID_VERSION'] || '7' +when /7/ + gem 'mongoid', '~> 7.0' when /6/ gem 'mongoid', '~> 6.0' when /5/ diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index b9a3fb4..6c3d84a 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -95,7 +95,7 @@ def fulltext_search_ensure_indexes(index_name, config) all_filter_keys |= keys.find_all { |key| key.starts_with?('filter_values.') } next unless keys & correct_keys != correct_keys Mongoid.logger.info "Dropping #{idef['name']} [#{keys & correct_keys} <=> #{correct_keys}]" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.drop_one(idef['key']) else coll.indexes.drop(idef['key']) @@ -108,14 +108,14 @@ def fulltext_search_ensure_indexes(index_name, config) end Mongoid.logger.info "Ensuring fts_index on #{coll.name}: #{index_definition}" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.create_one(Hash[index_definition], name: 'fts_index') else coll.indexes.create(Hash[index_definition], name: 'fts_index') end Mongoid.logger.info "Ensuring document_id index on #{coll.name}" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.create_one('document_id' => 1) # to make removes fast else coll.indexes.create('document_id' => 1) # to make removes fast @@ -282,7 +282,7 @@ def all_ngrams(str, config, bound_number_returned = true) def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('class' => name).delete_many else coll.find('class' => name).remove_all @@ -328,7 +328,7 @@ def update_ngram_index # remove existing ngrams from external index coll = collection.database[index_name.to_sym] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => _id).delete_many else coll.find('document_id' => _id).remove_all @@ -352,7 +352,7 @@ def update_ngram_index ngrams.each_pair do |ngram, score| index_document = { 'ngram' => ngram, 'document_id' => _id, 'score' => score, 'class' => self.class.name } index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.insert_one(index_document) else coll.insert(index_document) @@ -364,7 +364,7 @@ def update_ngram_index def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => _id).delete_many else coll.find('document_id' => _id).remove_all diff --git a/mongoid_fulltext.gemspec b/mongoid_fulltext.gemspec index 361ced4..6c48d70 100644 --- a/mongoid_fulltext.gemspec +++ b/mongoid_fulltext.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |s| s.homepage = 'https://github.com/mongoid/mongoid_fulltext' s.licenses = ['MIT'] s.summary = 'Full-text search for the Mongoid ORM, using n-grams extracted from text.' - s.add_dependency 'mongoid', '>= 3.0' + s.add_dependency 'mongoid', '>= 3.0', '< 8' s.add_dependency 'mongoid-compatibility' s.add_dependency 'unicode_utils' end diff --git a/spec/mongoid/full_text_search_spec.rb b/spec/mongoid/full_text_search_spec.rb index a385122..693bbe1 100644 --- a/spec/mongoid/full_text_search_spec.rb +++ b/spec/mongoid/full_text_search_spec.rb @@ -597,7 +597,7 @@ context 'incremental' do it 'removes an existing record' do coll = Mongoid.default_session['mongoid_fulltext.index_basicartwork_0'] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => flowers1._id).delete_many else coll.find('document_id' => flowers1._id).remove_all diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4a41651..46d6cfb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,6 +24,6 @@ end c.before :all do Mongoid.logger.level = Logger::INFO - Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? end end diff --git a/spec/support/mongoid.rb b/spec/support/mongoid.rb index 788b045..d73d317 100644 --- a/spec/support/mongoid.rb +++ b/spec/support/mongoid.rb @@ -2,4 +2,4 @@ module Mongoid def self.default_session default_client end -end if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? +end if Mongoid::Compatibility::Version.mongoid5_or_newer? From 65c22023f494001077323df6aee42d8128403e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:18:45 +0200 Subject: [PATCH 02/67] readd danger --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8e48b6a..63a9a84 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,8 @@ matrix: - rvm: 2.5.0 env: - MONGOID_VERSION=7.0 + before_script: + - bundle exec danger - rvm: 2.3.1 env: - MONGOID_VERSION=6.0 From 4364224e3be6a32e73017395b87ae2d9ee234c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:25:29 +0200 Subject: [PATCH 03/67] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68f51cf..6fd4122 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 0.8.1 (Next) +* [#35](https://github.com/mongoid/mongoid_fulltext/pull/35): Mongoid 7 compatibility - [@tomasc](https://github.com/tomasc). * Your contribution here. ### 0.8.0 (1/19/2017) From 6a6fd8c265e54977f288abee1ab53fae50a0e61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 15:55:48 +0200 Subject: [PATCH 04/67] SCI support --- lib/mongoid/full_text_search.rb | 10 +++++++- spec/models/my_doc.rb | 7 ++++++ spec/models/my_further_inherited_doc.rb | 2 ++ spec/models/my_inherited_doc.rb | 2 ++ spec/mongoid/sci_search_spec.rb | 31 +++++++++++++++++++++++++ spec/spec_helper.rb | 7 +++--- 6 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 spec/models/my_doc.rb create mode 100644 spec/models/my_further_inherited_doc.rb create mode 100644 spec/models/my_inherited_doc.rb create mode 100644 spec/mongoid/sci_search_spec.rb diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index 6c3d84a..b3c3f12 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -143,6 +143,7 @@ def fulltext_search(query_string, options = {}) coll = collection.database[index_name] cursors = ngrams.map do |ngram| query = { 'ngram' => ngram[0] } + query.update(document_type_filters) query.update(map_query_filters options) count = coll.find(query).count { ngram: ngram, count: count, query: query } @@ -296,6 +297,13 @@ def update_ngram_index private + # add filter by type according to SCI classes + def document_type_filters + return {} unless fields['_type'].present? + kls = ([self] + descendants).map(&:to_s) + { 'document_type' => { "$in" => kls } } + end + # Take a list of filters to be mapped so they can update the query # used upon the fulltext search of the ngrams def map_query_filters(filters) @@ -350,7 +358,7 @@ def update_ngram_index end # insert new ngrams in external index ngrams.each_pair do |ngram, score| - index_document = { 'ngram' => ngram, 'document_id' => _id, 'score' => score, 'class' => self.class.name } + index_document = { 'ngram' => ngram, 'document_id' => _id, 'document_type' => model_name.to_s, 'score' => score, 'class' => self.class.name } index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.insert_one(index_document) diff --git a/spec/models/my_doc.rb b/spec/models/my_doc.rb new file mode 100644 index 0000000..aab9e8d --- /dev/null +++ b/spec/models/my_doc.rb @@ -0,0 +1,7 @@ +class MyDoc + include Mongoid::Document + include Mongoid::FullTextSearch + + field :title + fulltext_search_in :title +end diff --git a/spec/models/my_further_inherited_doc.rb b/spec/models/my_further_inherited_doc.rb new file mode 100644 index 0000000..2184c03 --- /dev/null +++ b/spec/models/my_further_inherited_doc.rb @@ -0,0 +1,2 @@ +class MyFurtherInheritedDoc < MyInheritedDoc +end diff --git a/spec/models/my_inherited_doc.rb b/spec/models/my_inherited_doc.rb new file mode 100644 index 0000000..3cd0109 --- /dev/null +++ b/spec/models/my_inherited_doc.rb @@ -0,0 +1,2 @@ +class MyInheritedDoc < MyDoc +end diff --git a/spec/mongoid/sci_search_spec.rb b/spec/mongoid/sci_search_spec.rb new file mode 100644 index 0000000..d7651eb --- /dev/null +++ b/spec/mongoid/sci_search_spec.rb @@ -0,0 +1,31 @@ +# coding: utf-8 +require 'spec_helper' + +describe Mongoid::FullTextSearch do + context 'SCI' do + let!(:my_doc) { MyDoc.create!(title: 'My Doc') } + let!(:my_inherited_doc) { MyInheritedDoc.create!(title: 'My Inherited Doc') } + let!(:my_further_inherited_doc) { MyFurtherInheritedDoc.create!(title: 'My Inherited Doc') } + + context 'root class returns results for subclasses' do + let(:result) { MyDoc.fulltext_search("doc") } + it { expect(result).to include my_doc } + it { expect(result).to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + + context 'child class does not return superclass' do + let(:result) { MyInheritedDoc.fulltext_search("doc") } + it { expect(result).not_to include my_doc } + it { expect(result).to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + + context 'child class does not return superclass' do + let(:result) { MyFurtherInheritedDoc.fulltext_search("doc") } + it { expect(result).not_to include my_doc } + it { expect(result).not_to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 46d6cfb..e313fa9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,6 +15,9 @@ config.connect_to('mongoid_fulltext_test') end +Mongoid.logger.level = Logger::INFO +Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? + RSpec.configure do |c| c.before :each do Mongoid.purge! @@ -22,8 +25,4 @@ c.after :all do Mongoid.purge! end - c.before :all do - Mongoid.logger.level = Logger::INFO - Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? - end end From 9f57c799cb5186f70dd4d9c65b8cd130903547e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:25:44 +0200 Subject: [PATCH 05/67] add support for criteria --- lib/mongoid/full_text_search.rb | 6 +++++- spec/models/my_doc.rb | 2 ++ spec/mongoid/criteria_search_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 spec/mongoid/criteria_search_spec.rb diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index b3c3f12..e1f16aa 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -193,7 +193,11 @@ def fulltext_search(query_string, options = {}) end def instantiate_mapreduce_result(result) - result[:clazz].constantize.find(result[:id]) + if criteria.selector.empty? + result[:clazz].constantize.find(result[:id]) + else + criteria.where(_id: result[:id]).first + end end def instantiate_mapreduce_results(results, options) diff --git a/spec/models/my_doc.rb b/spec/models/my_doc.rb index aab9e8d..0a87892 100644 --- a/spec/models/my_doc.rb +++ b/spec/models/my_doc.rb @@ -3,5 +3,7 @@ class MyDoc include Mongoid::FullTextSearch field :title + field :value, type: Integer + fulltext_search_in :title end diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb new file mode 100644 index 0000000..6854b9f --- /dev/null +++ b/spec/mongoid/criteria_search_spec.rb @@ -0,0 +1,20 @@ +# coding: utf-8 +require 'spec_helper' + +describe Mongoid::FullTextSearch do + context 'Criteria' do + let!(:my_doc_1) { MyDoc.create!(title: 'My Doc 1') } + let!(:my_doc_2) { MyDoc.create!(title: 'My Doc 2', value: 10) } + + let(:result) do + begin + MyDoc.where(value: 10).fulltext_search("doc") + rescue + nil + end + end + + it { expect(result).not_to include my_doc_1 } + it { expect(result).to include my_doc_2 } + end +end From d4f634cd0cba4d9bccbad824efe220cdd0dc2c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:31:14 +0200 Subject: [PATCH 06/67] update README --- README.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04ceb96..ca20e95 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,40 @@ the AND of all of the individual results for each of the fields. Finally, if a f but criteria for that filter aren't passed to `fulltext_search`, the result is as if the filter had never been defined - you see both models that both pass and fail the filter in the results. +SCI Support +----------- + +The search respects SCI. From the spec: + +```ruby +class MyDoc + include Mongoid::Document + include Mongoid::FullTextSearch + + field :title + fulltext_search_in :title +end + +class MyInheritedDoc < MyDoc +end +``` + +```ruby +MyDoc.fulltext_search(…) # => will return both MyDoc as well as MyInheritedDoc documents +MyInheritedDoc.fulltext_search(…) # => will return only MyInheritedDoc documents +``` + +Criteria Support +---------------- + +It is also possible to pre-empt the search with Monogid criteria: + +```ruby +MyDoc.where(value: 10).fulltext_search(…) +``` + +Please not that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). + Indexing Options ---------------- @@ -397,4 +431,3 @@ Copyright and License MIT License, see [LICENSE](LICENSE) for details. (c) 2011-2017 [Artsy Inc.](http://artsy.github.io) - From 70c7ea6d8422c822414861c1efab5e9b7fc59720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:31:24 +0200 Subject: [PATCH 07/67] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca20e95..17d76db 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ It is also possible to pre-empt the search with Monogid criteria: MyDoc.where(value: 10).fulltext_search(…) ``` -Please not that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). +Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). Indexing Options ---------------- From 8d6afe2cb654b86a6958b3e90f1c912e98386a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:34:46 +0200 Subject: [PATCH 08/67] further explain --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 17d76db..b0709e4 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ It is also possible to pre-empt the search with Monogid criteria: MyDoc.where(value: 10).fulltext_search(…) ``` -Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). +Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance), since a criteria applies only to one class. Indexing Options ---------------- From e6a1a090fc2ba562beab8b126f47f97aeb05b443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 17:04:00 +0200 Subject: [PATCH 09/67] cleanup --- spec/mongoid/criteria_search_spec.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb index 6854b9f..7c94570 100644 --- a/spec/mongoid/criteria_search_spec.rb +++ b/spec/mongoid/criteria_search_spec.rb @@ -6,13 +6,7 @@ let!(:my_doc_1) { MyDoc.create!(title: 'My Doc 1') } let!(:my_doc_2) { MyDoc.create!(title: 'My Doc 2', value: 10) } - let(:result) do - begin - MyDoc.where(value: 10).fulltext_search("doc") - rescue - nil - end - end + let(:result) { MyDoc.where(value: 10).fulltext_search("doc") } it { expect(result).not_to include my_doc_1 } it { expect(result).to include my_doc_2 } From 94a2361f0b6a00cf324b3dbff326e6ab805a47b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 17:07:11 +0200 Subject: [PATCH 10/67] mongoid-compatibility added _or_newer? in 0.5.1 --- mongoid_fulltext.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoid_fulltext.gemspec b/mongoid_fulltext.gemspec index 6c48d70..f54c13c 100644 --- a/mongoid_fulltext.gemspec +++ b/mongoid_fulltext.gemspec @@ -14,6 +14,6 @@ Gem::Specification.new do |s| s.licenses = ['MIT'] s.summary = 'Full-text search for the Mongoid ORM, using n-grams extracted from text.' s.add_dependency 'mongoid', '>= 3.0', '< 8' - s.add_dependency 'mongoid-compatibility' + s.add_dependency 'mongoid-compatibility', '>= 0.5.1' s.add_dependency 'unicode_utils' end From 878b210b450ea37308a63940596c63665eb9ad28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 17:11:35 +0200 Subject: [PATCH 11/67] add database_cleaner --- mongoid_fulltext.gemspec | 1 + spec/spec_helper.rb | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/mongoid_fulltext.gemspec b/mongoid_fulltext.gemspec index f54c13c..681aa60 100644 --- a/mongoid_fulltext.gemspec +++ b/mongoid_fulltext.gemspec @@ -16,4 +16,5 @@ Gem::Specification.new do |s| s.add_dependency 'mongoid', '>= 3.0', '< 8' s.add_dependency 'mongoid-compatibility', '>= 0.5.1' s.add_dependency 'unicode_utils' + s.add_development_dependency 'database_cleaner' end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 46d6cfb..13e2950 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,6 +3,7 @@ require 'rspec' require 'mongoid' +require 'database_cleaner' ENV['MONGOID_ENV'] = 'test' @@ -15,15 +16,17 @@ config.connect_to('mongoid_fulltext_test') end +Mongoid.logger.level = Logger::INFO +Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? + +DatabaseCleaner.orm = :mongoid +DatabaseCleaner.strategy = :truncation + RSpec.configure do |c| c.before :each do - Mongoid.purge! + DatabaseCleaner.clean end c.after :all do - Mongoid.purge! - end - c.before :all do - Mongoid.logger.level = Logger::INFO - Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? + DatabaseCleaner.clean end end From 3bf0a2a85900a64ecc21eee5ab4232e970222ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 18:47:44 +0200 Subject: [PATCH 12/67] localized fields support --- lib/mongoid/full_text_search.rb | 120 ++++++++++++++++---------- spec/models/my_localized_doc.rb | 8 ++ spec/mongoid/localized_fields_spec.rb | 29 +++++++ 3 files changed, 110 insertions(+), 47 deletions(-) create mode 100644 spec/models/my_localized_doc.rb create mode 100644 spec/mongoid/localized_fields_spec.rb diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index e1f16aa..ec518bc 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -70,10 +70,18 @@ def fulltext_search_in(*args) def create_fulltext_indexes return unless mongoid_fulltext_config mongoid_fulltext_config.each_pair do |index_name, fulltext_config| - fulltext_search_ensure_indexes(index_name, fulltext_config) + ::I18n.available_locales.each do |locale| + fulltext_search_ensure_indexes(localized_index_name(index_name, locale), fulltext_config) + end end end + def localized_index_name(index_name, locale) + return index_name unless fields.values.any?(&:localized?) + return index_name unless ::I18n.available_locales.count > 1 + "#{index_name}_#{locale}" + end + def fulltext_search_ensure_indexes(index_name, config) db = collection.database coll = db[index_name] @@ -131,6 +139,7 @@ def fulltext_search(query_string, options = {}) end index_name = options.key?(:index) ? options.delete(:index) : mongoid_fulltext_config.keys.first + loc_index_name = localized_index_name(index_name, ::I18n.locale) # Options hash should only contain filters after this point ngrams = all_ngrams(query_string, mongoid_fulltext_config[index_name]) @@ -140,7 +149,7 @@ def fulltext_search(query_string, options = {}) # get a count of the number of index documents containing that n-gram ordering = { 'score' => -1 } limit = mongoid_fulltext_config[index_name][:max_candidate_set_size] - coll = collection.database[index_name] + coll = collection.database[loc_index_name] cursors = ngrams.map do |ngram| query = { 'ngram' => ngram[0] } query.update(document_type_filters) @@ -286,11 +295,13 @@ def all_ngrams(str, config, bound_number_returned = true) def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| - coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5_or_newer? - coll.find('class' => name).delete_many - else - coll.find('class' => name).remove_all + ::I18n.available_locales.each do |locale| + coll = collection.database[localized_index_name(index_name, locale)] + if Mongoid::Compatibility::Version.mongoid5_or_newer? + coll.find('class' => name).delete_many + else + coll.find('class' => name).remove_all + end end end end @@ -329,45 +340,58 @@ def format_query_filter(operator, key, value) def update_ngram_index mongoid_fulltext_config.each_pair do |index_name, fulltext_config| - if condition = fulltext_config[:update_if] - case condition - when Symbol then next unless send condition - when String then next unless instance_eval condition - when Proc then next unless condition.call self - else; next + ::I18n.available_locales.each do |locale| + loc_index_name = self.class.localized_index_name(index_name, locale) + + if condition = fulltext_config[:update_if] + case condition + when Symbol then next unless send condition + when String then next unless instance_eval condition + when Proc then next unless condition.call self + else; next + end end - end - # remove existing ngrams from external index - coll = collection.database[index_name.to_sym] - if Mongoid::Compatibility::Version.mongoid5_or_newer? - coll.find('document_id' => _id).delete_many - else - coll.find('document_id' => _id).remove_all - end - # extract ngrams from fields - field_values = fulltext_config[:ngram_fields].map { |field| send(field) } - ngrams = field_values.inject({}) { |accum, item| accum.update(self.class.all_ngrams(item, fulltext_config, false)) } - return if ngrams.empty? - # apply filters, if necessary - filter_values = nil - if fulltext_config.key?(:filters) - filter_values = Hash[fulltext_config[:filters].map do |key, value| - begin - [key, value.call(self)] - rescue - # Suppress any exceptions caused by filters - end - end.compact] - end - # insert new ngrams in external index - ngrams.each_pair do |ngram, score| - index_document = { 'ngram' => ngram, 'document_id' => _id, 'document_type' => model_name.to_s, 'score' => score, 'class' => self.class.name } - index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) + # remove existing ngrams from external index + coll = collection.database[loc_index_name.to_sym] if Mongoid::Compatibility::Version.mongoid5_or_newer? - coll.insert_one(index_document) + coll.find('document_id' => _id).delete_many else - coll.insert(index_document) + coll.find('document_id' => _id).remove_all + end + # extract ngrams from fields + field_values = fulltext_config[:ngram_fields].map do |field_name| + next send(field_name) if field_name == :to_s + next unless field = self.class.fields[field_name.to_s] + if field.localized? + send("#{field_name}_translations")[locale] + else + send(field_name) + end + end + + ngrams = field_values.inject({}) { |accum, item| accum.update(self.class.all_ngrams(item, fulltext_config, false)) } + return if ngrams.empty? + # apply filters, if necessary + filter_values = nil + if fulltext_config.key?(:filters) + filter_values = Hash[fulltext_config[:filters].map do |key, value| + begin + [key, value.call(self)] + rescue + # Suppress any exceptions caused by filters + end + end.compact] + end + # insert new ngrams in external index + ngrams.each_pair do |ngram, score| + index_document = { 'ngram' => ngram, 'document_id' => _id, 'document_type' => model_name.to_s, 'score' => score, 'class' => self.class.name } + index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) + if Mongoid::Compatibility::Version.mongoid5_or_newer? + coll.insert_one(index_document) + else + coll.insert(index_document) + end end end end @@ -375,11 +399,13 @@ def update_ngram_index def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| - coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5_or_newer? - coll.find('document_id' => _id).delete_many - else - coll.find('document_id' => _id).remove_all + ::I18n.available_locales.each do |locale| + coll = collection.database[self.class.localized_index_name(index_name, locale)] + if Mongoid::Compatibility::Version.mongoid5_or_newer? + coll.find('document_id' => _id).delete_many + else + coll.find('document_id' => _id).remove_all + end end end end diff --git a/spec/models/my_localized_doc.rb b/spec/models/my_localized_doc.rb new file mode 100644 index 0000000..5c6e116 --- /dev/null +++ b/spec/models/my_localized_doc.rb @@ -0,0 +1,8 @@ +class MyLocalizedDoc + include Mongoid::Document + include Mongoid::FullTextSearch + + field :title, localize: true + + fulltext_search_in :title +end diff --git a/spec/mongoid/localized_fields_spec.rb b/spec/mongoid/localized_fields_spec.rb new file mode 100644 index 0000000..2cf46a8 --- /dev/null +++ b/spec/mongoid/localized_fields_spec.rb @@ -0,0 +1,29 @@ +# coding: utf-8 +require 'spec_helper' + +describe Mongoid::FullTextSearch do + context 'Localized fields' do + let!(:my_doc) { MyLocalizedDoc.create!(title_translations: { en: 'Title', cs: "Nazev" }) } + + before(:each) do + @default_locale = ::I18n.locale + ::I18n.locale = locale + end + + after(:each) do + ::I18n.locale = @default_locale + end + + context 'en' do + let(:locale) { :en } + it { expect(MyLocalizedDoc.fulltext_search("title")).to include my_doc } + it { expect(MyLocalizedDoc.fulltext_search("nazev")).not_to include my_doc } + end + + context 'cs' do + let(:locale) { :cs } + it { expect(MyLocalizedDoc.fulltext_search("title")).not_to include my_doc } + it { expect(MyLocalizedDoc.fulltext_search("nazev")).to include my_doc } + end + end +end From 8e818bd042d1e5523cf2f4e97ec8be9b76b8615f Mon Sep 17 00:00:00 2001 From: dblock Date: Sat, 5 May 2018 15:43:33 -0400 Subject: [PATCH 13/67] Use database_cleaner. --- .travis.yml | 2 +- mongoid_fulltext.gemspec | 3 ++- spec/spec_helper.rb | 15 +++++++++------ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8d3c306..31acee2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,6 @@ services: mongodb addons: apt: sources: - - mongodb-3.2-precise + - mongodb-3.4-precise packages: - mongodb-org-server diff --git a/mongoid_fulltext.gemspec b/mongoid_fulltext.gemspec index 361ced4..5b8b62a 100644 --- a/mongoid_fulltext.gemspec +++ b/mongoid_fulltext.gemspec @@ -14,6 +14,7 @@ Gem::Specification.new do |s| s.licenses = ['MIT'] s.summary = 'Full-text search for the Mongoid ORM, using n-grams extracted from text.' s.add_dependency 'mongoid', '>= 3.0' - s.add_dependency 'mongoid-compatibility' + s.add_dependency 'mongoid-compatibility', '>= 0.5.1' s.add_dependency 'unicode_utils' + s.add_development_dependency 'database_cleaner' end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4a41651..849707d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,6 +3,7 @@ require 'rspec' require 'mongoid' +require 'database_cleaner' ENV['MONGOID_ENV'] = 'test' @@ -11,19 +12,21 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } Dir["#{File.dirname(__FILE__)}/models/**/*.rb"].each { |f| require f } +DatabaseCleaner.orm = :mongoid +DatabaseCleaner.strategy = :truncation + +Mongoid.logger.level = Logger::INFO +Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? + Mongoid.configure do |config| config.connect_to('mongoid_fulltext_test') end RSpec.configure do |c| c.before :each do - Mongoid.purge! + DatabaseCleaner.clean end c.after :all do - Mongoid.purge! - end - c.before :all do - Mongoid.logger.level = Logger::INFO - Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + DatabaseCleaner.clean end end From a6eeef914f715ac164343ba3205450cd4fbc9dad Mon Sep 17 00:00:00 2001 From: dblock Date: Sun, 6 May 2018 12:39:21 -0400 Subject: [PATCH 14/67] Mark failing specs pending. --- spec/mongoid/full_text_search_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/mongoid/full_text_search_spec.rb b/spec/mongoid/full_text_search_spec.rb index a385122..3c024cc 100644 --- a/spec/mongoid/full_text_search_spec.rb +++ b/spec/mongoid/full_text_search_spec.rb @@ -355,6 +355,8 @@ # fields as well as the union of all the filter fields to allow for efficient lookups. it 'creates a proper index for searching efficiently' do + # see https://github.com/mongoid/mongoid_fulltext/pull/39 + pending unless Mongoid::Compatibility::Version.mongoid5_or_newer? [FilteredArtwork, FilteredArtist, FilteredOther].each(&:create_indexes) index_collection = FilteredArtwork.collection.database['mongoid_fulltext.artworks_and_artists'] ngram_indexes = [] @@ -609,6 +611,8 @@ context 'mongoid indexes' do it 'can re-create dropped indexes' do + # see https://github.com/mongoid/mongoid_fulltext/pull/39 + pending unless Mongoid::Compatibility::Version.mongoid5_or_newer? # there're no indexes by default as Mongoid.autocreate_indexes is set to false # but mongo will automatically attempt to index _id in the background expect(Mongoid.default_session['mongoid_fulltext.index_basicartwork_0'].indexes.count).to be <= 1 From 82eab98b65363fe318593d4ed0c811a4792b3e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:18:07 +0200 Subject: [PATCH 15/67] Mongoid 7 compatibility --- .travis.yml | 5 +++-- Gemfile | 4 +++- lib/mongoid/full_text_search.rb | 14 +++++++------- mongoid_fulltext.gemspec | 4 ++-- spec/mongoid/full_text_search_spec.rb | 2 +- spec/support/mongoid.rb | 2 +- 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 31acee2..37aa435 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,12 @@ sudo: false matrix: include: + - rvm: 2.5.0 + env: + - MONGOID_VERSION=7.0 - rvm: 2.3.1 env: - MONGOID_VERSION=6.0 - before_script: - - bundle exec danger - rvm: 2.3.1 env: - MONGOID_VERSION=5.0 diff --git a/Gemfile b/Gemfile index 01dcc47..1a8278b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,8 @@ source 'http://rubygems.org' -case version = ENV['MONGOID_VERSION'] || '6' +case version = ENV['MONGOID_VERSION'] || '7' +when /7/ + gem 'mongoid', '~> 7.0' when /6/ gem 'mongoid', '~> 6.0' when /5/ diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index b9a3fb4..6c3d84a 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -95,7 +95,7 @@ def fulltext_search_ensure_indexes(index_name, config) all_filter_keys |= keys.find_all { |key| key.starts_with?('filter_values.') } next unless keys & correct_keys != correct_keys Mongoid.logger.info "Dropping #{idef['name']} [#{keys & correct_keys} <=> #{correct_keys}]" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.drop_one(idef['key']) else coll.indexes.drop(idef['key']) @@ -108,14 +108,14 @@ def fulltext_search_ensure_indexes(index_name, config) end Mongoid.logger.info "Ensuring fts_index on #{coll.name}: #{index_definition}" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.create_one(Hash[index_definition], name: 'fts_index') else coll.indexes.create(Hash[index_definition], name: 'fts_index') end Mongoid.logger.info "Ensuring document_id index on #{coll.name}" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.create_one('document_id' => 1) # to make removes fast else coll.indexes.create('document_id' => 1) # to make removes fast @@ -282,7 +282,7 @@ def all_ngrams(str, config, bound_number_returned = true) def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('class' => name).delete_many else coll.find('class' => name).remove_all @@ -328,7 +328,7 @@ def update_ngram_index # remove existing ngrams from external index coll = collection.database[index_name.to_sym] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => _id).delete_many else coll.find('document_id' => _id).remove_all @@ -352,7 +352,7 @@ def update_ngram_index ngrams.each_pair do |ngram, score| index_document = { 'ngram' => ngram, 'document_id' => _id, 'score' => score, 'class' => self.class.name } index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.insert_one(index_document) else coll.insert(index_document) @@ -364,7 +364,7 @@ def update_ngram_index def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => _id).delete_many else coll.find('document_id' => _id).remove_all diff --git a/mongoid_fulltext.gemspec b/mongoid_fulltext.gemspec index 5b8b62a..451f560 100644 --- a/mongoid_fulltext.gemspec +++ b/mongoid_fulltext.gemspec @@ -13,8 +13,8 @@ Gem::Specification.new do |s| s.homepage = 'https://github.com/mongoid/mongoid_fulltext' s.licenses = ['MIT'] s.summary = 'Full-text search for the Mongoid ORM, using n-grams extracted from text.' - s.add_dependency 'mongoid', '>= 3.0' - s.add_dependency 'mongoid-compatibility', '>= 0.5.1' + s.add_dependency 'mongoid', '>= 3.0', '< 8' + s.add_dependency 'mongoid-compatibility' s.add_dependency 'unicode_utils' s.add_development_dependency 'database_cleaner' end diff --git a/spec/mongoid/full_text_search_spec.rb b/spec/mongoid/full_text_search_spec.rb index 3c024cc..1d81994 100644 --- a/spec/mongoid/full_text_search_spec.rb +++ b/spec/mongoid/full_text_search_spec.rb @@ -599,7 +599,7 @@ context 'incremental' do it 'removes an existing record' do coll = Mongoid.default_session['mongoid_fulltext.index_basicartwork_0'] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => flowers1._id).delete_many else coll.find('document_id' => flowers1._id).remove_all diff --git a/spec/support/mongoid.rb b/spec/support/mongoid.rb index 788b045..d73d317 100644 --- a/spec/support/mongoid.rb +++ b/spec/support/mongoid.rb @@ -2,4 +2,4 @@ module Mongoid def self.default_session default_client end -end if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? +end if Mongoid::Compatibility::Version.mongoid5_or_newer? From 8b3ccb5354daeb5788c40608aed3238112960aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:18:45 +0200 Subject: [PATCH 16/67] readd danger --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 37aa435..d207a6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,8 @@ matrix: - rvm: 2.5.0 env: - MONGOID_VERSION=7.0 + before_script: + - bundle exec danger - rvm: 2.3.1 env: - MONGOID_VERSION=6.0 From 57abbea68c2375e2808ba38f3113f7e32be3d0d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:25:29 +0200 Subject: [PATCH 17/67] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68f51cf..6fd4122 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 0.8.1 (Next) +* [#35](https://github.com/mongoid/mongoid_fulltext/pull/35): Mongoid 7 compatibility - [@tomasc](https://github.com/tomasc). * Your contribution here. ### 0.8.0 (1/19/2017) From b59427dd62bf8dfe6b17b0df7aa0f3cbfaa92228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 15:55:48 +0200 Subject: [PATCH 18/67] SCI support --- lib/mongoid/full_text_search.rb | 10 +++++++- spec/models/my_doc.rb | 7 ++++++ spec/models/my_further_inherited_doc.rb | 2 ++ spec/models/my_inherited_doc.rb | 2 ++ spec/mongoid/sci_search_spec.rb | 31 +++++++++++++++++++++++++ spec/spec_helper.rb | 3 +++ 6 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 spec/models/my_doc.rb create mode 100644 spec/models/my_further_inherited_doc.rb create mode 100644 spec/models/my_inherited_doc.rb create mode 100644 spec/mongoid/sci_search_spec.rb diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index 6c3d84a..b3c3f12 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -143,6 +143,7 @@ def fulltext_search(query_string, options = {}) coll = collection.database[index_name] cursors = ngrams.map do |ngram| query = { 'ngram' => ngram[0] } + query.update(document_type_filters) query.update(map_query_filters options) count = coll.find(query).count { ngram: ngram, count: count, query: query } @@ -296,6 +297,13 @@ def update_ngram_index private + # add filter by type according to SCI classes + def document_type_filters + return {} unless fields['_type'].present? + kls = ([self] + descendants).map(&:to_s) + { 'document_type' => { "$in" => kls } } + end + # Take a list of filters to be mapped so they can update the query # used upon the fulltext search of the ngrams def map_query_filters(filters) @@ -350,7 +358,7 @@ def update_ngram_index end # insert new ngrams in external index ngrams.each_pair do |ngram, score| - index_document = { 'ngram' => ngram, 'document_id' => _id, 'score' => score, 'class' => self.class.name } + index_document = { 'ngram' => ngram, 'document_id' => _id, 'document_type' => model_name.to_s, 'score' => score, 'class' => self.class.name } index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.insert_one(index_document) diff --git a/spec/models/my_doc.rb b/spec/models/my_doc.rb new file mode 100644 index 0000000..aab9e8d --- /dev/null +++ b/spec/models/my_doc.rb @@ -0,0 +1,7 @@ +class MyDoc + include Mongoid::Document + include Mongoid::FullTextSearch + + field :title + fulltext_search_in :title +end diff --git a/spec/models/my_further_inherited_doc.rb b/spec/models/my_further_inherited_doc.rb new file mode 100644 index 0000000..2184c03 --- /dev/null +++ b/spec/models/my_further_inherited_doc.rb @@ -0,0 +1,2 @@ +class MyFurtherInheritedDoc < MyInheritedDoc +end diff --git a/spec/models/my_inherited_doc.rb b/spec/models/my_inherited_doc.rb new file mode 100644 index 0000000..3cd0109 --- /dev/null +++ b/spec/models/my_inherited_doc.rb @@ -0,0 +1,2 @@ +class MyInheritedDoc < MyDoc +end diff --git a/spec/mongoid/sci_search_spec.rb b/spec/mongoid/sci_search_spec.rb new file mode 100644 index 0000000..d7651eb --- /dev/null +++ b/spec/mongoid/sci_search_spec.rb @@ -0,0 +1,31 @@ +# coding: utf-8 +require 'spec_helper' + +describe Mongoid::FullTextSearch do + context 'SCI' do + let!(:my_doc) { MyDoc.create!(title: 'My Doc') } + let!(:my_inherited_doc) { MyInheritedDoc.create!(title: 'My Inherited Doc') } + let!(:my_further_inherited_doc) { MyFurtherInheritedDoc.create!(title: 'My Inherited Doc') } + + context 'root class returns results for subclasses' do + let(:result) { MyDoc.fulltext_search("doc") } + it { expect(result).to include my_doc } + it { expect(result).to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + + context 'child class does not return superclass' do + let(:result) { MyInheritedDoc.fulltext_search("doc") } + it { expect(result).not_to include my_doc } + it { expect(result).to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + + context 'child class does not return superclass' do + let(:result) { MyFurtherInheritedDoc.fulltext_search("doc") } + it { expect(result).not_to include my_doc } + it { expect(result).not_to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 849707d..44dc0b8 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,6 +22,9 @@ config.connect_to('mongoid_fulltext_test') end +Mongoid.logger.level = Logger::INFO +Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? + RSpec.configure do |c| c.before :each do DatabaseCleaner.clean From df1ccff1a8d6f9b840abca6c54ffc0e206161d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:25:44 +0200 Subject: [PATCH 19/67] add support for criteria --- lib/mongoid/full_text_search.rb | 6 +++++- spec/models/my_doc.rb | 2 ++ spec/mongoid/criteria_search_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 spec/mongoid/criteria_search_spec.rb diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index b3c3f12..e1f16aa 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -193,7 +193,11 @@ def fulltext_search(query_string, options = {}) end def instantiate_mapreduce_result(result) - result[:clazz].constantize.find(result[:id]) + if criteria.selector.empty? + result[:clazz].constantize.find(result[:id]) + else + criteria.where(_id: result[:id]).first + end end def instantiate_mapreduce_results(results, options) diff --git a/spec/models/my_doc.rb b/spec/models/my_doc.rb index aab9e8d..0a87892 100644 --- a/spec/models/my_doc.rb +++ b/spec/models/my_doc.rb @@ -3,5 +3,7 @@ class MyDoc include Mongoid::FullTextSearch field :title + field :value, type: Integer + fulltext_search_in :title end diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb new file mode 100644 index 0000000..6854b9f --- /dev/null +++ b/spec/mongoid/criteria_search_spec.rb @@ -0,0 +1,20 @@ +# coding: utf-8 +require 'spec_helper' + +describe Mongoid::FullTextSearch do + context 'Criteria' do + let!(:my_doc_1) { MyDoc.create!(title: 'My Doc 1') } + let!(:my_doc_2) { MyDoc.create!(title: 'My Doc 2', value: 10) } + + let(:result) do + begin + MyDoc.where(value: 10).fulltext_search("doc") + rescue + nil + end + end + + it { expect(result).not_to include my_doc_1 } + it { expect(result).to include my_doc_2 } + end +end From 9832f53b945975fe5c8cec918f78b3566ac6d7f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:31:14 +0200 Subject: [PATCH 20/67] update README --- README.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04ceb96..ca20e95 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,40 @@ the AND of all of the individual results for each of the fields. Finally, if a f but criteria for that filter aren't passed to `fulltext_search`, the result is as if the filter had never been defined - you see both models that both pass and fail the filter in the results. +SCI Support +----------- + +The search respects SCI. From the spec: + +```ruby +class MyDoc + include Mongoid::Document + include Mongoid::FullTextSearch + + field :title + fulltext_search_in :title +end + +class MyInheritedDoc < MyDoc +end +``` + +```ruby +MyDoc.fulltext_search(…) # => will return both MyDoc as well as MyInheritedDoc documents +MyInheritedDoc.fulltext_search(…) # => will return only MyInheritedDoc documents +``` + +Criteria Support +---------------- + +It is also possible to pre-empt the search with Monogid criteria: + +```ruby +MyDoc.where(value: 10).fulltext_search(…) +``` + +Please not that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). + Indexing Options ---------------- @@ -397,4 +431,3 @@ Copyright and License MIT License, see [LICENSE](LICENSE) for details. (c) 2011-2017 [Artsy Inc.](http://artsy.github.io) - From a9b7c36157ed6f0b500a3ed47a74c988b3bedefb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:31:24 +0200 Subject: [PATCH 21/67] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca20e95..17d76db 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ It is also possible to pre-empt the search with Monogid criteria: MyDoc.where(value: 10).fulltext_search(…) ``` -Please not that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). +Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). Indexing Options ---------------- From 4b21baae2ca9a85df6d4eea8d0f5af41797d1106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:34:46 +0200 Subject: [PATCH 22/67] further explain --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 17d76db..b0709e4 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ It is also possible to pre-empt the search with Monogid criteria: MyDoc.where(value: 10).fulltext_search(…) ``` -Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). +Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance), since a criteria applies only to one class. Indexing Options ---------------- From 13bdee390d5d09f6933b1a403a09d930896b7439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 17:04:00 +0200 Subject: [PATCH 23/67] cleanup --- spec/mongoid/criteria_search_spec.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb index 6854b9f..7c94570 100644 --- a/spec/mongoid/criteria_search_spec.rb +++ b/spec/mongoid/criteria_search_spec.rb @@ -6,13 +6,7 @@ let!(:my_doc_1) { MyDoc.create!(title: 'My Doc 1') } let!(:my_doc_2) { MyDoc.create!(title: 'My Doc 2', value: 10) } - let(:result) do - begin - MyDoc.where(value: 10).fulltext_search("doc") - rescue - nil - end - end + let(:result) { MyDoc.where(value: 10).fulltext_search("doc") } it { expect(result).not_to include my_doc_1 } it { expect(result).to include my_doc_2 } From 5dcd0cdb73d1d5ca40eebdc7319a0a9462f7e5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:18:07 +0200 Subject: [PATCH 24/67] Mongoid 7 compatibility --- .travis.yml | 5 +++-- Gemfile | 4 +++- lib/mongoid/full_text_search.rb | 14 +++++++------- spec/mongoid/full_text_search_spec.rb | 2 +- spec/support/mongoid.rb | 2 +- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 31acee2..37aa435 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,12 @@ sudo: false matrix: include: + - rvm: 2.5.0 + env: + - MONGOID_VERSION=7.0 - rvm: 2.3.1 env: - MONGOID_VERSION=6.0 - before_script: - - bundle exec danger - rvm: 2.3.1 env: - MONGOID_VERSION=5.0 diff --git a/Gemfile b/Gemfile index 01dcc47..1a8278b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,8 @@ source 'http://rubygems.org' -case version = ENV['MONGOID_VERSION'] || '6' +case version = ENV['MONGOID_VERSION'] || '7' +when /7/ + gem 'mongoid', '~> 7.0' when /6/ gem 'mongoid', '~> 6.0' when /5/ diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index b9a3fb4..6c3d84a 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -95,7 +95,7 @@ def fulltext_search_ensure_indexes(index_name, config) all_filter_keys |= keys.find_all { |key| key.starts_with?('filter_values.') } next unless keys & correct_keys != correct_keys Mongoid.logger.info "Dropping #{idef['name']} [#{keys & correct_keys} <=> #{correct_keys}]" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.drop_one(idef['key']) else coll.indexes.drop(idef['key']) @@ -108,14 +108,14 @@ def fulltext_search_ensure_indexes(index_name, config) end Mongoid.logger.info "Ensuring fts_index on #{coll.name}: #{index_definition}" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.create_one(Hash[index_definition], name: 'fts_index') else coll.indexes.create(Hash[index_definition], name: 'fts_index') end Mongoid.logger.info "Ensuring document_id index on #{coll.name}" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.create_one('document_id' => 1) # to make removes fast else coll.indexes.create('document_id' => 1) # to make removes fast @@ -282,7 +282,7 @@ def all_ngrams(str, config, bound_number_returned = true) def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('class' => name).delete_many else coll.find('class' => name).remove_all @@ -328,7 +328,7 @@ def update_ngram_index # remove existing ngrams from external index coll = collection.database[index_name.to_sym] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => _id).delete_many else coll.find('document_id' => _id).remove_all @@ -352,7 +352,7 @@ def update_ngram_index ngrams.each_pair do |ngram, score| index_document = { 'ngram' => ngram, 'document_id' => _id, 'score' => score, 'class' => self.class.name } index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.insert_one(index_document) else coll.insert(index_document) @@ -364,7 +364,7 @@ def update_ngram_index def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => _id).delete_many else coll.find('document_id' => _id).remove_all diff --git a/spec/mongoid/full_text_search_spec.rb b/spec/mongoid/full_text_search_spec.rb index 3c024cc..1d81994 100644 --- a/spec/mongoid/full_text_search_spec.rb +++ b/spec/mongoid/full_text_search_spec.rb @@ -599,7 +599,7 @@ context 'incremental' do it 'removes an existing record' do coll = Mongoid.default_session['mongoid_fulltext.index_basicartwork_0'] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => flowers1._id).delete_many else coll.find('document_id' => flowers1._id).remove_all diff --git a/spec/support/mongoid.rb b/spec/support/mongoid.rb index 788b045..d73d317 100644 --- a/spec/support/mongoid.rb +++ b/spec/support/mongoid.rb @@ -2,4 +2,4 @@ module Mongoid def self.default_session default_client end -end if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? +end if Mongoid::Compatibility::Version.mongoid5_or_newer? From 20fbcdf813a274a485ffd67b3177b3035cd84d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:18:45 +0200 Subject: [PATCH 25/67] readd danger --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 37aa435..d207a6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,8 @@ matrix: - rvm: 2.5.0 env: - MONGOID_VERSION=7.0 + before_script: + - bundle exec danger - rvm: 2.3.1 env: - MONGOID_VERSION=6.0 From 1ff06cc8ee0fefe5ba99b60fcfb4d3b03e05121c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:25:29 +0200 Subject: [PATCH 26/67] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68f51cf..6fd4122 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 0.8.1 (Next) +* [#35](https://github.com/mongoid/mongoid_fulltext/pull/35): Mongoid 7 compatibility - [@tomasc](https://github.com/tomasc). * Your contribution here. ### 0.8.0 (1/19/2017) From 6c8ba8c58d747613397aefd07151ab5acea4bf39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 17:07:11 +0200 Subject: [PATCH 27/67] mongoid-compatibility added _or_newer? in 0.5.1 --- mongoid_fulltext.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoid_fulltext.gemspec b/mongoid_fulltext.gemspec index 5b8b62a..681aa60 100644 --- a/mongoid_fulltext.gemspec +++ b/mongoid_fulltext.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |s| s.homepage = 'https://github.com/mongoid/mongoid_fulltext' s.licenses = ['MIT'] s.summary = 'Full-text search for the Mongoid ORM, using n-grams extracted from text.' - s.add_dependency 'mongoid', '>= 3.0' + s.add_dependency 'mongoid', '>= 3.0', '< 8' s.add_dependency 'mongoid-compatibility', '>= 0.5.1' s.add_dependency 'unicode_utils' s.add_development_dependency 'database_cleaner' From 6ff4ce6ffbdeba86f1cf9dc7382825f7c3812e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 17:11:35 +0200 Subject: [PATCH 28/67] add database_cleaner --- spec/spec_helper.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 849707d..c06b4dd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,6 +22,12 @@ config.connect_to('mongoid_fulltext_test') end +Mongoid.logger.level = Logger::INFO +Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? + +DatabaseCleaner.orm = :mongoid +DatabaseCleaner.strategy = :truncation + RSpec.configure do |c| c.before :each do DatabaseCleaner.clean From 7dd9949174293866b4b6c124d8e0add5b0eeb7db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:18:07 +0200 Subject: [PATCH 29/67] Mongoid 7 compatibility --- .travis.yml | 5 +++-- Gemfile | 4 +++- lib/mongoid/full_text_search.rb | 14 +++++++------- mongoid_fulltext.gemspec | 4 ++-- spec/mongoid/full_text_search_spec.rb | 2 +- spec/support/mongoid.rb | 2 +- 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 31acee2..37aa435 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,12 @@ sudo: false matrix: include: + - rvm: 2.5.0 + env: + - MONGOID_VERSION=7.0 - rvm: 2.3.1 env: - MONGOID_VERSION=6.0 - before_script: - - bundle exec danger - rvm: 2.3.1 env: - MONGOID_VERSION=5.0 diff --git a/Gemfile b/Gemfile index 01dcc47..1a8278b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,8 @@ source 'http://rubygems.org' -case version = ENV['MONGOID_VERSION'] || '6' +case version = ENV['MONGOID_VERSION'] || '7' +when /7/ + gem 'mongoid', '~> 7.0' when /6/ gem 'mongoid', '~> 6.0' when /5/ diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index b9a3fb4..6c3d84a 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -95,7 +95,7 @@ def fulltext_search_ensure_indexes(index_name, config) all_filter_keys |= keys.find_all { |key| key.starts_with?('filter_values.') } next unless keys & correct_keys != correct_keys Mongoid.logger.info "Dropping #{idef['name']} [#{keys & correct_keys} <=> #{correct_keys}]" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.drop_one(idef['key']) else coll.indexes.drop(idef['key']) @@ -108,14 +108,14 @@ def fulltext_search_ensure_indexes(index_name, config) end Mongoid.logger.info "Ensuring fts_index on #{coll.name}: #{index_definition}" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.create_one(Hash[index_definition], name: 'fts_index') else coll.indexes.create(Hash[index_definition], name: 'fts_index') end Mongoid.logger.info "Ensuring document_id index on #{coll.name}" if Mongoid.logger - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.indexes.create_one('document_id' => 1) # to make removes fast else coll.indexes.create('document_id' => 1) # to make removes fast @@ -282,7 +282,7 @@ def all_ngrams(str, config, bound_number_returned = true) def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('class' => name).delete_many else coll.find('class' => name).remove_all @@ -328,7 +328,7 @@ def update_ngram_index # remove existing ngrams from external index coll = collection.database[index_name.to_sym] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => _id).delete_many else coll.find('document_id' => _id).remove_all @@ -352,7 +352,7 @@ def update_ngram_index ngrams.each_pair do |ngram, score| index_document = { 'ngram' => ngram, 'document_id' => _id, 'score' => score, 'class' => self.class.name } index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.insert_one(index_document) else coll.insert(index_document) @@ -364,7 +364,7 @@ def update_ngram_index def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => _id).delete_many else coll.find('document_id' => _id).remove_all diff --git a/mongoid_fulltext.gemspec b/mongoid_fulltext.gemspec index 5b8b62a..451f560 100644 --- a/mongoid_fulltext.gemspec +++ b/mongoid_fulltext.gemspec @@ -13,8 +13,8 @@ Gem::Specification.new do |s| s.homepage = 'https://github.com/mongoid/mongoid_fulltext' s.licenses = ['MIT'] s.summary = 'Full-text search for the Mongoid ORM, using n-grams extracted from text.' - s.add_dependency 'mongoid', '>= 3.0' - s.add_dependency 'mongoid-compatibility', '>= 0.5.1' + s.add_dependency 'mongoid', '>= 3.0', '< 8' + s.add_dependency 'mongoid-compatibility' s.add_dependency 'unicode_utils' s.add_development_dependency 'database_cleaner' end diff --git a/spec/mongoid/full_text_search_spec.rb b/spec/mongoid/full_text_search_spec.rb index 3c024cc..1d81994 100644 --- a/spec/mongoid/full_text_search_spec.rb +++ b/spec/mongoid/full_text_search_spec.rb @@ -599,7 +599,7 @@ context 'incremental' do it 'removes an existing record' do coll = Mongoid.default_session['mongoid_fulltext.index_basicartwork_0'] - if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? + if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.find('document_id' => flowers1._id).delete_many else coll.find('document_id' => flowers1._id).remove_all diff --git a/spec/support/mongoid.rb b/spec/support/mongoid.rb index 788b045..d73d317 100644 --- a/spec/support/mongoid.rb +++ b/spec/support/mongoid.rb @@ -2,4 +2,4 @@ module Mongoid def self.default_session default_client end -end if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? +end if Mongoid::Compatibility::Version.mongoid5_or_newer? From 240f5475c5f879642061656a75499db6164f7d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:18:45 +0200 Subject: [PATCH 30/67] readd danger --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 37aa435..d207a6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,8 @@ matrix: - rvm: 2.5.0 env: - MONGOID_VERSION=7.0 + before_script: + - bundle exec danger - rvm: 2.3.1 env: - MONGOID_VERSION=6.0 From e2c5b7a36519c6ac948f88644f35b85dbc9faa8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:25:29 +0200 Subject: [PATCH 31/67] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68f51cf..6fd4122 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 0.8.1 (Next) +* [#35](https://github.com/mongoid/mongoid_fulltext/pull/35): Mongoid 7 compatibility - [@tomasc](https://github.com/tomasc). * Your contribution here. ### 0.8.0 (1/19/2017) From 287b8ad73824681ae180d71f8f64521246432c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 15:55:48 +0200 Subject: [PATCH 32/67] SCI support --- lib/mongoid/full_text_search.rb | 10 +++++++- spec/models/my_doc.rb | 7 ++++++ spec/models/my_further_inherited_doc.rb | 2 ++ spec/models/my_inherited_doc.rb | 2 ++ spec/mongoid/sci_search_spec.rb | 31 +++++++++++++++++++++++++ spec/spec_helper.rb | 3 +++ 6 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 spec/models/my_doc.rb create mode 100644 spec/models/my_further_inherited_doc.rb create mode 100644 spec/models/my_inherited_doc.rb create mode 100644 spec/mongoid/sci_search_spec.rb diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index 6c3d84a..b3c3f12 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -143,6 +143,7 @@ def fulltext_search(query_string, options = {}) coll = collection.database[index_name] cursors = ngrams.map do |ngram| query = { 'ngram' => ngram[0] } + query.update(document_type_filters) query.update(map_query_filters options) count = coll.find(query).count { ngram: ngram, count: count, query: query } @@ -296,6 +297,13 @@ def update_ngram_index private + # add filter by type according to SCI classes + def document_type_filters + return {} unless fields['_type'].present? + kls = ([self] + descendants).map(&:to_s) + { 'document_type' => { "$in" => kls } } + end + # Take a list of filters to be mapped so they can update the query # used upon the fulltext search of the ngrams def map_query_filters(filters) @@ -350,7 +358,7 @@ def update_ngram_index end # insert new ngrams in external index ngrams.each_pair do |ngram, score| - index_document = { 'ngram' => ngram, 'document_id' => _id, 'score' => score, 'class' => self.class.name } + index_document = { 'ngram' => ngram, 'document_id' => _id, 'document_type' => model_name.to_s, 'score' => score, 'class' => self.class.name } index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.insert_one(index_document) diff --git a/spec/models/my_doc.rb b/spec/models/my_doc.rb new file mode 100644 index 0000000..aab9e8d --- /dev/null +++ b/spec/models/my_doc.rb @@ -0,0 +1,7 @@ +class MyDoc + include Mongoid::Document + include Mongoid::FullTextSearch + + field :title + fulltext_search_in :title +end diff --git a/spec/models/my_further_inherited_doc.rb b/spec/models/my_further_inherited_doc.rb new file mode 100644 index 0000000..2184c03 --- /dev/null +++ b/spec/models/my_further_inherited_doc.rb @@ -0,0 +1,2 @@ +class MyFurtherInheritedDoc < MyInheritedDoc +end diff --git a/spec/models/my_inherited_doc.rb b/spec/models/my_inherited_doc.rb new file mode 100644 index 0000000..3cd0109 --- /dev/null +++ b/spec/models/my_inherited_doc.rb @@ -0,0 +1,2 @@ +class MyInheritedDoc < MyDoc +end diff --git a/spec/mongoid/sci_search_spec.rb b/spec/mongoid/sci_search_spec.rb new file mode 100644 index 0000000..d7651eb --- /dev/null +++ b/spec/mongoid/sci_search_spec.rb @@ -0,0 +1,31 @@ +# coding: utf-8 +require 'spec_helper' + +describe Mongoid::FullTextSearch do + context 'SCI' do + let!(:my_doc) { MyDoc.create!(title: 'My Doc') } + let!(:my_inherited_doc) { MyInheritedDoc.create!(title: 'My Inherited Doc') } + let!(:my_further_inherited_doc) { MyFurtherInheritedDoc.create!(title: 'My Inherited Doc') } + + context 'root class returns results for subclasses' do + let(:result) { MyDoc.fulltext_search("doc") } + it { expect(result).to include my_doc } + it { expect(result).to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + + context 'child class does not return superclass' do + let(:result) { MyInheritedDoc.fulltext_search("doc") } + it { expect(result).not_to include my_doc } + it { expect(result).to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + + context 'child class does not return superclass' do + let(:result) { MyFurtherInheritedDoc.fulltext_search("doc") } + it { expect(result).not_to include my_doc } + it { expect(result).not_to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 849707d..44dc0b8 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,6 +22,9 @@ config.connect_to('mongoid_fulltext_test') end +Mongoid.logger.level = Logger::INFO +Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? + RSpec.configure do |c| c.before :each do DatabaseCleaner.clean From ce149155f6959b7dd0969aaa524566696b0375fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:25:44 +0200 Subject: [PATCH 33/67] add support for criteria --- lib/mongoid/full_text_search.rb | 6 +++++- spec/models/my_doc.rb | 2 ++ spec/mongoid/criteria_search_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 spec/mongoid/criteria_search_spec.rb diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index b3c3f12..e1f16aa 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -193,7 +193,11 @@ def fulltext_search(query_string, options = {}) end def instantiate_mapreduce_result(result) - result[:clazz].constantize.find(result[:id]) + if criteria.selector.empty? + result[:clazz].constantize.find(result[:id]) + else + criteria.where(_id: result[:id]).first + end end def instantiate_mapreduce_results(results, options) diff --git a/spec/models/my_doc.rb b/spec/models/my_doc.rb index aab9e8d..0a87892 100644 --- a/spec/models/my_doc.rb +++ b/spec/models/my_doc.rb @@ -3,5 +3,7 @@ class MyDoc include Mongoid::FullTextSearch field :title + field :value, type: Integer + fulltext_search_in :title end diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb new file mode 100644 index 0000000..6854b9f --- /dev/null +++ b/spec/mongoid/criteria_search_spec.rb @@ -0,0 +1,20 @@ +# coding: utf-8 +require 'spec_helper' + +describe Mongoid::FullTextSearch do + context 'Criteria' do + let!(:my_doc_1) { MyDoc.create!(title: 'My Doc 1') } + let!(:my_doc_2) { MyDoc.create!(title: 'My Doc 2', value: 10) } + + let(:result) do + begin + MyDoc.where(value: 10).fulltext_search("doc") + rescue + nil + end + end + + it { expect(result).not_to include my_doc_1 } + it { expect(result).to include my_doc_2 } + end +end From 7be12fa0791e786bd6a8fc9159201ca7e0c1b90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:31:14 +0200 Subject: [PATCH 34/67] update README --- README.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04ceb96..ca20e95 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,40 @@ the AND of all of the individual results for each of the fields. Finally, if a f but criteria for that filter aren't passed to `fulltext_search`, the result is as if the filter had never been defined - you see both models that both pass and fail the filter in the results. +SCI Support +----------- + +The search respects SCI. From the spec: + +```ruby +class MyDoc + include Mongoid::Document + include Mongoid::FullTextSearch + + field :title + fulltext_search_in :title +end + +class MyInheritedDoc < MyDoc +end +``` + +```ruby +MyDoc.fulltext_search(…) # => will return both MyDoc as well as MyInheritedDoc documents +MyInheritedDoc.fulltext_search(…) # => will return only MyInheritedDoc documents +``` + +Criteria Support +---------------- + +It is also possible to pre-empt the search with Monogid criteria: + +```ruby +MyDoc.where(value: 10).fulltext_search(…) +``` + +Please not that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). + Indexing Options ---------------- @@ -397,4 +431,3 @@ Copyright and License MIT License, see [LICENSE](LICENSE) for details. (c) 2011-2017 [Artsy Inc.](http://artsy.github.io) - From cac1fa4cd6bc455130537124efe884a23fcfed8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:31:24 +0200 Subject: [PATCH 35/67] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca20e95..17d76db 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ It is also possible to pre-empt the search with Monogid criteria: MyDoc.where(value: 10).fulltext_search(…) ``` -Please not that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). +Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). Indexing Options ---------------- From 85c9152fc72241bd2c5d087e5215574f92b3573b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:34:46 +0200 Subject: [PATCH 36/67] further explain --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 17d76db..b0709e4 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ It is also possible to pre-empt the search with Monogid criteria: MyDoc.where(value: 10).fulltext_search(…) ``` -Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). +Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance), since a criteria applies only to one class. Indexing Options ---------------- From b77df68dd805fca2f4c671a5fbbca500397a0d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 17:04:00 +0200 Subject: [PATCH 37/67] cleanup --- spec/mongoid/criteria_search_spec.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb index 6854b9f..7c94570 100644 --- a/spec/mongoid/criteria_search_spec.rb +++ b/spec/mongoid/criteria_search_spec.rb @@ -6,13 +6,7 @@ let!(:my_doc_1) { MyDoc.create!(title: 'My Doc 1') } let!(:my_doc_2) { MyDoc.create!(title: 'My Doc 2', value: 10) } - let(:result) do - begin - MyDoc.where(value: 10).fulltext_search("doc") - rescue - nil - end - end + let(:result) { MyDoc.where(value: 10).fulltext_search("doc") } it { expect(result).not_to include my_doc_1 } it { expect(result).to include my_doc_2 } From 335fa6ec532396e7421da288d6b1e35750e5d8ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 17:07:11 +0200 Subject: [PATCH 38/67] mongoid-compatibility added _or_newer? in 0.5.1 --- mongoid_fulltext.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoid_fulltext.gemspec b/mongoid_fulltext.gemspec index 451f560..681aa60 100644 --- a/mongoid_fulltext.gemspec +++ b/mongoid_fulltext.gemspec @@ -14,7 +14,7 @@ Gem::Specification.new do |s| s.licenses = ['MIT'] s.summary = 'Full-text search for the Mongoid ORM, using n-grams extracted from text.' s.add_dependency 'mongoid', '>= 3.0', '< 8' - s.add_dependency 'mongoid-compatibility' + s.add_dependency 'mongoid-compatibility', '>= 0.5.1' s.add_dependency 'unicode_utils' s.add_development_dependency 'database_cleaner' end From 4d9b5c9ef1498ab3dc71a979d29632e52992807b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 17:11:35 +0200 Subject: [PATCH 39/67] add database_cleaner --- spec/spec_helper.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 44dc0b8..c06b4dd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -25,6 +25,9 @@ Mongoid.logger.level = Logger::INFO Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? +DatabaseCleaner.orm = :mongoid +DatabaseCleaner.strategy = :truncation + RSpec.configure do |c| c.before :each do DatabaseCleaner.clean From 3bd912e0b159f4d9eea26be1fd4304a4ae49a772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 18:47:44 +0200 Subject: [PATCH 40/67] localized fields support --- lib/mongoid/full_text_search.rb | 120 ++++++++++++++++---------- spec/models/my_localized_doc.rb | 8 ++ spec/mongoid/localized_fields_spec.rb | 29 +++++++ 3 files changed, 110 insertions(+), 47 deletions(-) create mode 100644 spec/models/my_localized_doc.rb create mode 100644 spec/mongoid/localized_fields_spec.rb diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index e1f16aa..ec518bc 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -70,10 +70,18 @@ def fulltext_search_in(*args) def create_fulltext_indexes return unless mongoid_fulltext_config mongoid_fulltext_config.each_pair do |index_name, fulltext_config| - fulltext_search_ensure_indexes(index_name, fulltext_config) + ::I18n.available_locales.each do |locale| + fulltext_search_ensure_indexes(localized_index_name(index_name, locale), fulltext_config) + end end end + def localized_index_name(index_name, locale) + return index_name unless fields.values.any?(&:localized?) + return index_name unless ::I18n.available_locales.count > 1 + "#{index_name}_#{locale}" + end + def fulltext_search_ensure_indexes(index_name, config) db = collection.database coll = db[index_name] @@ -131,6 +139,7 @@ def fulltext_search(query_string, options = {}) end index_name = options.key?(:index) ? options.delete(:index) : mongoid_fulltext_config.keys.first + loc_index_name = localized_index_name(index_name, ::I18n.locale) # Options hash should only contain filters after this point ngrams = all_ngrams(query_string, mongoid_fulltext_config[index_name]) @@ -140,7 +149,7 @@ def fulltext_search(query_string, options = {}) # get a count of the number of index documents containing that n-gram ordering = { 'score' => -1 } limit = mongoid_fulltext_config[index_name][:max_candidate_set_size] - coll = collection.database[index_name] + coll = collection.database[loc_index_name] cursors = ngrams.map do |ngram| query = { 'ngram' => ngram[0] } query.update(document_type_filters) @@ -286,11 +295,13 @@ def all_ngrams(str, config, bound_number_returned = true) def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| - coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5_or_newer? - coll.find('class' => name).delete_many - else - coll.find('class' => name).remove_all + ::I18n.available_locales.each do |locale| + coll = collection.database[localized_index_name(index_name, locale)] + if Mongoid::Compatibility::Version.mongoid5_or_newer? + coll.find('class' => name).delete_many + else + coll.find('class' => name).remove_all + end end end end @@ -329,45 +340,58 @@ def format_query_filter(operator, key, value) def update_ngram_index mongoid_fulltext_config.each_pair do |index_name, fulltext_config| - if condition = fulltext_config[:update_if] - case condition - when Symbol then next unless send condition - when String then next unless instance_eval condition - when Proc then next unless condition.call self - else; next + ::I18n.available_locales.each do |locale| + loc_index_name = self.class.localized_index_name(index_name, locale) + + if condition = fulltext_config[:update_if] + case condition + when Symbol then next unless send condition + when String then next unless instance_eval condition + when Proc then next unless condition.call self + else; next + end end - end - # remove existing ngrams from external index - coll = collection.database[index_name.to_sym] - if Mongoid::Compatibility::Version.mongoid5_or_newer? - coll.find('document_id' => _id).delete_many - else - coll.find('document_id' => _id).remove_all - end - # extract ngrams from fields - field_values = fulltext_config[:ngram_fields].map { |field| send(field) } - ngrams = field_values.inject({}) { |accum, item| accum.update(self.class.all_ngrams(item, fulltext_config, false)) } - return if ngrams.empty? - # apply filters, if necessary - filter_values = nil - if fulltext_config.key?(:filters) - filter_values = Hash[fulltext_config[:filters].map do |key, value| - begin - [key, value.call(self)] - rescue - # Suppress any exceptions caused by filters - end - end.compact] - end - # insert new ngrams in external index - ngrams.each_pair do |ngram, score| - index_document = { 'ngram' => ngram, 'document_id' => _id, 'document_type' => model_name.to_s, 'score' => score, 'class' => self.class.name } - index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) + # remove existing ngrams from external index + coll = collection.database[loc_index_name.to_sym] if Mongoid::Compatibility::Version.mongoid5_or_newer? - coll.insert_one(index_document) + coll.find('document_id' => _id).delete_many else - coll.insert(index_document) + coll.find('document_id' => _id).remove_all + end + # extract ngrams from fields + field_values = fulltext_config[:ngram_fields].map do |field_name| + next send(field_name) if field_name == :to_s + next unless field = self.class.fields[field_name.to_s] + if field.localized? + send("#{field_name}_translations")[locale] + else + send(field_name) + end + end + + ngrams = field_values.inject({}) { |accum, item| accum.update(self.class.all_ngrams(item, fulltext_config, false)) } + return if ngrams.empty? + # apply filters, if necessary + filter_values = nil + if fulltext_config.key?(:filters) + filter_values = Hash[fulltext_config[:filters].map do |key, value| + begin + [key, value.call(self)] + rescue + # Suppress any exceptions caused by filters + end + end.compact] + end + # insert new ngrams in external index + ngrams.each_pair do |ngram, score| + index_document = { 'ngram' => ngram, 'document_id' => _id, 'document_type' => model_name.to_s, 'score' => score, 'class' => self.class.name } + index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) + if Mongoid::Compatibility::Version.mongoid5_or_newer? + coll.insert_one(index_document) + else + coll.insert(index_document) + end end end end @@ -375,11 +399,13 @@ def update_ngram_index def remove_from_ngram_index mongoid_fulltext_config.each_pair do |index_name, _fulltext_config| - coll = collection.database[index_name] - if Mongoid::Compatibility::Version.mongoid5_or_newer? - coll.find('document_id' => _id).delete_many - else - coll.find('document_id' => _id).remove_all + ::I18n.available_locales.each do |locale| + coll = collection.database[self.class.localized_index_name(index_name, locale)] + if Mongoid::Compatibility::Version.mongoid5_or_newer? + coll.find('document_id' => _id).delete_many + else + coll.find('document_id' => _id).remove_all + end end end end diff --git a/spec/models/my_localized_doc.rb b/spec/models/my_localized_doc.rb new file mode 100644 index 0000000..5c6e116 --- /dev/null +++ b/spec/models/my_localized_doc.rb @@ -0,0 +1,8 @@ +class MyLocalizedDoc + include Mongoid::Document + include Mongoid::FullTextSearch + + field :title, localize: true + + fulltext_search_in :title +end diff --git a/spec/mongoid/localized_fields_spec.rb b/spec/mongoid/localized_fields_spec.rb new file mode 100644 index 0000000..2cf46a8 --- /dev/null +++ b/spec/mongoid/localized_fields_spec.rb @@ -0,0 +1,29 @@ +# coding: utf-8 +require 'spec_helper' + +describe Mongoid::FullTextSearch do + context 'Localized fields' do + let!(:my_doc) { MyLocalizedDoc.create!(title_translations: { en: 'Title', cs: "Nazev" }) } + + before(:each) do + @default_locale = ::I18n.locale + ::I18n.locale = locale + end + + after(:each) do + ::I18n.locale = @default_locale + end + + context 'en' do + let(:locale) { :en } + it { expect(MyLocalizedDoc.fulltext_search("title")).to include my_doc } + it { expect(MyLocalizedDoc.fulltext_search("nazev")).not_to include my_doc } + end + + context 'cs' do + let(:locale) { :cs } + it { expect(MyLocalizedDoc.fulltext_search("title")).not_to include my_doc } + it { expect(MyLocalizedDoc.fulltext_search("nazev")).to include my_doc } + end + end +end From 71320418f892fd5383c6fd860374d63ece042f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Mon, 7 May 2018 12:00:24 +0200 Subject: [PATCH 41/67] make Rubocop happy --- lib/mongoid/full_text_search.rb | 2 +- spec/mongoid/criteria_search_spec.rb | 2 +- spec/mongoid/sci_search_spec.rb | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index e1f16aa..b30311d 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -305,7 +305,7 @@ def update_ngram_index def document_type_filters return {} unless fields['_type'].present? kls = ([self] + descendants).map(&:to_s) - { 'document_type' => { "$in" => kls } } + { 'document_type' => { '$in' => kls } } end # Take a list of filters to be mapped so they can update the query diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb index 7c94570..e07abb3 100644 --- a/spec/mongoid/criteria_search_spec.rb +++ b/spec/mongoid/criteria_search_spec.rb @@ -6,7 +6,7 @@ let!(:my_doc_1) { MyDoc.create!(title: 'My Doc 1') } let!(:my_doc_2) { MyDoc.create!(title: 'My Doc 2', value: 10) } - let(:result) { MyDoc.where(value: 10).fulltext_search("doc") } + let(:result) { MyDoc.where(value: 10).fulltext_search('doc') } it { expect(result).not_to include my_doc_1 } it { expect(result).to include my_doc_2 } diff --git a/spec/mongoid/sci_search_spec.rb b/spec/mongoid/sci_search_spec.rb index d7651eb..aacb07a 100644 --- a/spec/mongoid/sci_search_spec.rb +++ b/spec/mongoid/sci_search_spec.rb @@ -8,21 +8,21 @@ let!(:my_further_inherited_doc) { MyFurtherInheritedDoc.create!(title: 'My Inherited Doc') } context 'root class returns results for subclasses' do - let(:result) { MyDoc.fulltext_search("doc") } + let(:result) { MyDoc.fulltext_search('doc') } it { expect(result).to include my_doc } it { expect(result).to include my_inherited_doc } it { expect(result).to include my_further_inherited_doc } end context 'child class does not return superclass' do - let(:result) { MyInheritedDoc.fulltext_search("doc") } + let(:result) { MyInheritedDoc.fulltext_search('doc') } it { expect(result).not_to include my_doc } it { expect(result).to include my_inherited_doc } it { expect(result).to include my_further_inherited_doc } end context 'child class does not return superclass' do - let(:result) { MyFurtherInheritedDoc.fulltext_search("doc") } + let(:result) { MyFurtherInheritedDoc.fulltext_search('doc') } it { expect(result).not_to include my_doc } it { expect(result).not_to include my_inherited_doc } it { expect(result).to include my_further_inherited_doc } From b172e64eab0ede4b38db0083149110d54ff6abf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Mon, 7 May 2018 12:03:56 +0200 Subject: [PATCH 42/67] fix RuboCop too many lines --- lib/mongoid/full_text_search.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index b30311d..1adf738 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -56,13 +56,11 @@ def fulltext_search_in(*args) } config.update(options) - args = [:to_s] if args.empty? config[:ngram_fields] = args config[:alphabet] = Hash[config[:alphabet].split('').map { |ch| [ch, ch] }] config[:word_separators] = Hash[config[:word_separators].split('').map { |ch| [ch, ch] }] mongoid_fulltext_config[index_name] = config - before_save(:update_ngram_index) if config[:reindex_immediately] before_destroy :remove_from_ngram_index end From fafbf1cbda0011526f2b845b6712c91811919f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Mon, 7 May 2018 12:07:10 +0200 Subject: [PATCH 43/67] Revert "fix RuboCop too many lines" This reverts commit b172e64eab0ede4b38db0083149110d54ff6abf7. --- lib/mongoid/full_text_search.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index 1adf738..b30311d 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -56,11 +56,13 @@ def fulltext_search_in(*args) } config.update(options) + args = [:to_s] if args.empty? config[:ngram_fields] = args config[:alphabet] = Hash[config[:alphabet].split('').map { |ch| [ch, ch] }] config[:word_separators] = Hash[config[:word_separators].split('').map { |ch| [ch, ch] }] mongoid_fulltext_config[index_name] = config + before_save(:update_ngram_index) if config[:reindex_immediately] before_destroy :remove_from_ngram_index end From ff04f9c43d4e814b56ff75526d1ddfcb3f320cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Mon, 7 May 2018 12:07:33 +0200 Subject: [PATCH 44/67] bump module length --- .rubocop_todo.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 16c85f4..89d1a16 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -55,7 +55,7 @@ Metrics/MethodLength: # Offense count: 1 # Configuration parameters: CountComments. Metrics/ModuleLength: - Max: 224 + Max: 300 # Offense count: 4 Metrics/PerceivedComplexity: From a27b81e24ac0829aac6257dd875bf9507b9da80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Celizna?= Date: Mon, 7 May 2018 15:56:19 +0200 Subject: [PATCH 45/67] Update spec_helper.rb --- spec/spec_helper.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c06b4dd..849707d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,12 +22,6 @@ config.connect_to('mongoid_fulltext_test') end -Mongoid.logger.level = Logger::INFO -Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? - -DatabaseCleaner.orm = :mongoid -DatabaseCleaner.strategy = :truncation - RSpec.configure do |c| c.before :each do DatabaseCleaner.clean From 5b87ef2afdd09315d0845cf33ab7d95d8b2b0205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Tue, 8 May 2018 15:34:46 +0200 Subject: [PATCH 46/67] fix --- spec/support/mongoid.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/mongoid.rb b/spec/support/mongoid.rb index 0bb3f43..8185f17 100644 --- a/spec/support/mongoid.rb +++ b/spec/support/mongoid.rb @@ -4,4 +4,4 @@ def self.default_session default_client end end -end if Mongoid::Compatibility::Version.mongoid5_or_newer? +end From fe9f7a064ca569643e6fcdf5c2357363ad9c7dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Tue, 8 May 2018 15:36:29 +0200 Subject: [PATCH 47/67] rubocop --- .rubocop_todo.yml | 6 +++--- lib/mongoid/full_text_search.rb | 2 +- spec/mongoid/criteria_search_spec.rb | 2 +- spec/mongoid/sci_search_spec.rb | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a0ed496..475d6c3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2018-05-08 14:54:25 +0200 using RuboCop version 0.55.0. +# on 2018-05-08 15:36:14 +0200 using RuboCop version 0.55.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -64,7 +64,7 @@ Metrics/MethodLength: # Offense count: 1 # Configuration parameters: CountComments. Metrics/ModuleLength: - Max: 223 + Max: 233 # Offense count: 4 Metrics/PerceivedComplexity: @@ -129,7 +129,7 @@ Style/NumericPredicate: - 'spec/**/*' - 'lib/mongoid/full_text_search.rb' -# Offense count: 262 +# Offense count: 265 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index 9ab0fbd..efd569c 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -144,7 +144,7 @@ def fulltext_search(query_string, options = {}) cursors = ngrams.map do |ngram| query = { 'ngram' => ngram[0] } query.update(document_type_filters) - query.update(map_query_filters options) + query.update(map_query_filters(options)) count = coll.find(query).count { ngram: ngram, count: count, query: query } end.sort! { |record1, record2| record1[:count] <=> record2[:count] } diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb index e07abb3..2e5b8ff 100644 --- a/spec/mongoid/criteria_search_spec.rb +++ b/spec/mongoid/criteria_search_spec.rb @@ -1,4 +1,4 @@ -# coding: utf-8 + require 'spec_helper' describe Mongoid::FullTextSearch do diff --git a/spec/mongoid/sci_search_spec.rb b/spec/mongoid/sci_search_spec.rb index aacb07a..2b40e66 100644 --- a/spec/mongoid/sci_search_spec.rb +++ b/spec/mongoid/sci_search_spec.rb @@ -1,4 +1,4 @@ -# coding: utf-8 + require 'spec_helper' describe Mongoid::FullTextSearch do From 7078f9a7d62334dc7612c1cf87dbc4c87ff2b17a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:18:07 +0200 Subject: [PATCH 48/67] Mongoid 7 compatibility --- spec/support/mongoid.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/mongoid.rb b/spec/support/mongoid.rb index 8185f17..0bb3f43 100644 --- a/spec/support/mongoid.rb +++ b/spec/support/mongoid.rb @@ -4,4 +4,4 @@ def self.default_session default_client end end -end +end if Mongoid::Compatibility::Version.mongoid5_or_newer? From dc21126dc1f7d4c5dad4cdc2fd525a0b44cce85e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 11:25:29 +0200 Subject: [PATCH 49/67] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94b073f..862e0fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 0.8.3 (Next) +* [#35](https://github.com/mongoid/mongoid_fulltext/pull/35): Mongoid 7 compatibility - [@tomasc](https://github.com/tomasc). * Your contribution here. ### 0.8.2 (8/5/2018) From 9baa1906487ba2748c4a888b4726b50085539732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 15:55:48 +0200 Subject: [PATCH 50/67] SCI support --- lib/mongoid/full_text_search.rb | 12 ++++++++-- spec/models/my_doc.rb | 7 ++++++ spec/models/my_further_inherited_doc.rb | 2 ++ spec/models/my_inherited_doc.rb | 2 ++ spec/mongoid/sci_search_spec.rb | 31 +++++++++++++++++++++++++ spec/spec_helper.rb | 3 +++ 6 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 spec/models/my_doc.rb create mode 100644 spec/models/my_further_inherited_doc.rb create mode 100644 spec/models/my_inherited_doc.rb create mode 100644 spec/mongoid/sci_search_spec.rb diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index cf12703..cb8ef07 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -143,7 +143,8 @@ def fulltext_search(query_string, options = {}) coll = collection.database[index_name] cursors = ngrams.map do |ngram| query = { 'ngram' => ngram[0] } - query.update(map_query_filters(options)) + query.update(document_type_filters) + query.update(map_query_filters options) count = coll.find(query).count { ngram: ngram, count: count, query: query } end.sort! { |record1, record2| record1[:count] <=> record2[:count] } @@ -295,6 +296,13 @@ def update_ngram_index private + # add filter by type according to SCI classes + def document_type_filters + return {} unless fields['_type'].present? + kls = ([self] + descendants).map(&:to_s) + { 'document_type' => { "$in" => kls } } + end + # Take a list of filters to be mapped so they can update the query # used upon the fulltext search of the ngrams def map_query_filters(filters) @@ -349,7 +357,7 @@ def update_ngram_index end # insert new ngrams in external index ngrams.each_pair do |ngram, score| - index_document = { 'ngram' => ngram, 'document_id' => _id, 'score' => score, 'class' => self.class.name } + index_document = { 'ngram' => ngram, 'document_id' => _id, 'document_type' => model_name.to_s, 'score' => score, 'class' => self.class.name } index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.insert_one(index_document) diff --git a/spec/models/my_doc.rb b/spec/models/my_doc.rb new file mode 100644 index 0000000..aab9e8d --- /dev/null +++ b/spec/models/my_doc.rb @@ -0,0 +1,7 @@ +class MyDoc + include Mongoid::Document + include Mongoid::FullTextSearch + + field :title + fulltext_search_in :title +end diff --git a/spec/models/my_further_inherited_doc.rb b/spec/models/my_further_inherited_doc.rb new file mode 100644 index 0000000..2184c03 --- /dev/null +++ b/spec/models/my_further_inherited_doc.rb @@ -0,0 +1,2 @@ +class MyFurtherInheritedDoc < MyInheritedDoc +end diff --git a/spec/models/my_inherited_doc.rb b/spec/models/my_inherited_doc.rb new file mode 100644 index 0000000..3cd0109 --- /dev/null +++ b/spec/models/my_inherited_doc.rb @@ -0,0 +1,2 @@ +class MyInheritedDoc < MyDoc +end diff --git a/spec/mongoid/sci_search_spec.rb b/spec/mongoid/sci_search_spec.rb new file mode 100644 index 0000000..d7651eb --- /dev/null +++ b/spec/mongoid/sci_search_spec.rb @@ -0,0 +1,31 @@ +# coding: utf-8 +require 'spec_helper' + +describe Mongoid::FullTextSearch do + context 'SCI' do + let!(:my_doc) { MyDoc.create!(title: 'My Doc') } + let!(:my_inherited_doc) { MyInheritedDoc.create!(title: 'My Inherited Doc') } + let!(:my_further_inherited_doc) { MyFurtherInheritedDoc.create!(title: 'My Inherited Doc') } + + context 'root class returns results for subclasses' do + let(:result) { MyDoc.fulltext_search("doc") } + it { expect(result).to include my_doc } + it { expect(result).to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + + context 'child class does not return superclass' do + let(:result) { MyInheritedDoc.fulltext_search("doc") } + it { expect(result).not_to include my_doc } + it { expect(result).to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + + context 'child class does not return superclass' do + let(:result) { MyFurtherInheritedDoc.fulltext_search("doc") } + it { expect(result).not_to include my_doc } + it { expect(result).not_to include my_inherited_doc } + it { expect(result).to include my_further_inherited_doc } + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a01760d..7b86747 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,6 +22,9 @@ config.connect_to('mongoid_fulltext_test') end +Mongoid.logger.level = Logger::INFO +Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? + RSpec.configure do |c| c.before :each do DatabaseCleaner.clean From 0af33c2747f712bf383bf5d1d84dea3688fdf4ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:25:44 +0200 Subject: [PATCH 51/67] add support for criteria --- lib/mongoid/full_text_search.rb | 6 +++++- spec/models/my_doc.rb | 2 ++ spec/mongoid/criteria_search_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 spec/mongoid/criteria_search_spec.rb diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index cb8ef07..f570912 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -192,7 +192,11 @@ def fulltext_search(query_string, options = {}) end def instantiate_mapreduce_result(result) - result[:clazz].constantize.find(result[:id]) + if criteria.selector.empty? + result[:clazz].constantize.find(result[:id]) + else + criteria.where(_id: result[:id]).first + end end def instantiate_mapreduce_results(results, options) diff --git a/spec/models/my_doc.rb b/spec/models/my_doc.rb index aab9e8d..0a87892 100644 --- a/spec/models/my_doc.rb +++ b/spec/models/my_doc.rb @@ -3,5 +3,7 @@ class MyDoc include Mongoid::FullTextSearch field :title + field :value, type: Integer + fulltext_search_in :title end diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb new file mode 100644 index 0000000..6854b9f --- /dev/null +++ b/spec/mongoid/criteria_search_spec.rb @@ -0,0 +1,20 @@ +# coding: utf-8 +require 'spec_helper' + +describe Mongoid::FullTextSearch do + context 'Criteria' do + let!(:my_doc_1) { MyDoc.create!(title: 'My Doc 1') } + let!(:my_doc_2) { MyDoc.create!(title: 'My Doc 2', value: 10) } + + let(:result) do + begin + MyDoc.where(value: 10).fulltext_search("doc") + rescue + nil + end + end + + it { expect(result).not_to include my_doc_1 } + it { expect(result).to include my_doc_2 } + end +end From 880ef89a118e228153aa428eb0e7b9a35507828d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:31:14 +0200 Subject: [PATCH 52/67] update README --- README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/README.md b/README.md index 195d417..1ce7656 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,40 @@ the AND of all of the individual results for each of the fields. Finally, if a f but criteria for that filter aren't passed to `fulltext_search`, the result is as if the filter had never been defined - you see both models that both pass and fail the filter in the results. +SCI Support +----------- + +The search respects SCI. From the spec: + +```ruby +class MyDoc + include Mongoid::Document + include Mongoid::FullTextSearch + + field :title + fulltext_search_in :title +end + +class MyInheritedDoc < MyDoc +end +``` + +```ruby +MyDoc.fulltext_search(…) # => will return both MyDoc as well as MyInheritedDoc documents +MyInheritedDoc.fulltext_search(…) # => will return only MyInheritedDoc documents +``` + +Criteria Support +---------------- + +It is also possible to pre-empt the search with Monogid criteria: + +```ruby +MyDoc.where(value: 10).fulltext_search(…) +``` + +Please not that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). + Indexing Options ---------------- From 7ab7164b49648d54e3b588b4e93f0436c1239564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:31:24 +0200 Subject: [PATCH 53/67] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ce7656..de31bc9 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ It is also possible to pre-empt the search with Monogid criteria: MyDoc.where(value: 10).fulltext_search(…) ``` -Please not that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). +Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). Indexing Options ---------------- From d509b5efdf8d38b114da0f3e223b2f9f4842fbb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 16:34:46 +0200 Subject: [PATCH 54/67] further explain --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de31bc9..1791363 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ It is also possible to pre-empt the search with Monogid criteria: MyDoc.where(value: 10).fulltext_search(…) ``` -Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance). +Please note that this will not work in case an index is shared by multiple classes (that are not connected through inheritance), since a criteria applies only to one class. Indexing Options ---------------- From d278868dadc4bb85d82403e6dddef5110bed8156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Sat, 5 May 2018 17:04:00 +0200 Subject: [PATCH 55/67] cleanup --- spec/mongoid/criteria_search_spec.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb index 6854b9f..7c94570 100644 --- a/spec/mongoid/criteria_search_spec.rb +++ b/spec/mongoid/criteria_search_spec.rb @@ -6,13 +6,7 @@ let!(:my_doc_1) { MyDoc.create!(title: 'My Doc 1') } let!(:my_doc_2) { MyDoc.create!(title: 'My Doc 2', value: 10) } - let(:result) do - begin - MyDoc.where(value: 10).fulltext_search("doc") - rescue - nil - end - end + let(:result) { MyDoc.where(value: 10).fulltext_search("doc") } it { expect(result).not_to include my_doc_1 } it { expect(result).to include my_doc_2 } From ebc16e23f73bd3023b6122ac6c55df77677cc40f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Mon, 7 May 2018 12:00:24 +0200 Subject: [PATCH 56/67] make Rubocop happy --- lib/mongoid/full_text_search.rb | 2 +- spec/mongoid/criteria_search_spec.rb | 2 +- spec/mongoid/sci_search_spec.rb | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index f570912..9ab0fbd 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -304,7 +304,7 @@ def update_ngram_index def document_type_filters return {} unless fields['_type'].present? kls = ([self] + descendants).map(&:to_s) - { 'document_type' => { "$in" => kls } } + { 'document_type' => { '$in' => kls } } end # Take a list of filters to be mapped so they can update the query diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb index 7c94570..e07abb3 100644 --- a/spec/mongoid/criteria_search_spec.rb +++ b/spec/mongoid/criteria_search_spec.rb @@ -6,7 +6,7 @@ let!(:my_doc_1) { MyDoc.create!(title: 'My Doc 1') } let!(:my_doc_2) { MyDoc.create!(title: 'My Doc 2', value: 10) } - let(:result) { MyDoc.where(value: 10).fulltext_search("doc") } + let(:result) { MyDoc.where(value: 10).fulltext_search('doc') } it { expect(result).not_to include my_doc_1 } it { expect(result).to include my_doc_2 } diff --git a/spec/mongoid/sci_search_spec.rb b/spec/mongoid/sci_search_spec.rb index d7651eb..aacb07a 100644 --- a/spec/mongoid/sci_search_spec.rb +++ b/spec/mongoid/sci_search_spec.rb @@ -8,21 +8,21 @@ let!(:my_further_inherited_doc) { MyFurtherInheritedDoc.create!(title: 'My Inherited Doc') } context 'root class returns results for subclasses' do - let(:result) { MyDoc.fulltext_search("doc") } + let(:result) { MyDoc.fulltext_search('doc') } it { expect(result).to include my_doc } it { expect(result).to include my_inherited_doc } it { expect(result).to include my_further_inherited_doc } end context 'child class does not return superclass' do - let(:result) { MyInheritedDoc.fulltext_search("doc") } + let(:result) { MyInheritedDoc.fulltext_search('doc') } it { expect(result).not_to include my_doc } it { expect(result).to include my_inherited_doc } it { expect(result).to include my_further_inherited_doc } end context 'child class does not return superclass' do - let(:result) { MyFurtherInheritedDoc.fulltext_search("doc") } + let(:result) { MyFurtherInheritedDoc.fulltext_search('doc') } it { expect(result).not_to include my_doc } it { expect(result).not_to include my_inherited_doc } it { expect(result).to include my_further_inherited_doc } From dcde6b8d20c2257d5d47ac75d927dfc11376e239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Mon, 7 May 2018 12:03:56 +0200 Subject: [PATCH 57/67] fix RuboCop too many lines --- lib/mongoid/full_text_search.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index 9ab0fbd..d9e6ab1 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -56,13 +56,11 @@ def fulltext_search_in(*args) } config.update(options) - args = [:to_s] if args.empty? config[:ngram_fields] = args config[:alphabet] = Hash[config[:alphabet].split('').map { |ch| [ch, ch] }] config[:word_separators] = Hash[config[:word_separators].split('').map { |ch| [ch, ch] }] mongoid_fulltext_config[index_name] = config - before_save(:update_ngram_index) if config[:reindex_immediately] before_destroy :remove_from_ngram_index end From af8958c76663633b7249fdb7e1936c1fd93fc142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Mon, 7 May 2018 12:07:10 +0200 Subject: [PATCH 58/67] Revert "fix RuboCop too many lines" This reverts commit b172e64eab0ede4b38db0083149110d54ff6abf7. --- lib/mongoid/full_text_search.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index d9e6ab1..9ab0fbd 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -56,11 +56,13 @@ def fulltext_search_in(*args) } config.update(options) + args = [:to_s] if args.empty? config[:ngram_fields] = args config[:alphabet] = Hash[config[:alphabet].split('').map { |ch| [ch, ch] }] config[:word_separators] = Hash[config[:word_separators].split('').map { |ch| [ch, ch] }] mongoid_fulltext_config[index_name] = config + before_save(:update_ngram_index) if config[:reindex_immediately] before_destroy :remove_from_ngram_index end From 41a2fb45802ed35df26b766abf97709362d616a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Mon, 7 May 2018 12:07:33 +0200 Subject: [PATCH 59/67] bump module length --- .rubocop_todo.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a0ed496..a388bf3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -64,7 +64,7 @@ Metrics/MethodLength: # Offense count: 1 # Configuration parameters: CountComments. Metrics/ModuleLength: - Max: 223 + Max: 300 # Offense count: 4 Metrics/PerceivedComplexity: From 5c0946df34ff2c9d8cfbd1864565d1e1e7f1312e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Celizna?= Date: Mon, 7 May 2018 15:56:19 +0200 Subject: [PATCH 60/67] Update spec_helper.rb --- spec/spec_helper.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7b86747..a01760d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,9 +22,6 @@ config.connect_to('mongoid_fulltext_test') end -Mongoid.logger.level = Logger::INFO -Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer? - RSpec.configure do |c| c.before :each do DatabaseCleaner.clean From 95df3571a376256d8e71c584026c2c7aa14cec09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Tue, 8 May 2018 15:34:46 +0200 Subject: [PATCH 61/67] fix --- spec/support/mongoid.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/mongoid.rb b/spec/support/mongoid.rb index 0bb3f43..8185f17 100644 --- a/spec/support/mongoid.rb +++ b/spec/support/mongoid.rb @@ -4,4 +4,4 @@ def self.default_session default_client end end -end if Mongoid::Compatibility::Version.mongoid5_or_newer? +end From 22f5942ec3c02ba5c42da5a55d729b69a10d9b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Tue, 8 May 2018 15:36:29 +0200 Subject: [PATCH 62/67] rubocop --- .rubocop_todo.yml | 4 ++-- lib/mongoid/full_text_search.rb | 2 +- spec/mongoid/criteria_search_spec.rb | 2 +- spec/mongoid/sci_search_spec.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a388bf3..b31254d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2018-05-08 14:54:25 +0200 using RuboCop version 0.55.0. +# on 2018-05-08 15:36:14 +0200 using RuboCop version 0.55.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -129,7 +129,7 @@ Style/NumericPredicate: - 'spec/**/*' - 'lib/mongoid/full_text_search.rb' -# Offense count: 262 +# Offense count: 265 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index 9ab0fbd..efd569c 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -144,7 +144,7 @@ def fulltext_search(query_string, options = {}) cursors = ngrams.map do |ngram| query = { 'ngram' => ngram[0] } query.update(document_type_filters) - query.update(map_query_filters options) + query.update(map_query_filters(options)) count = coll.find(query).count { ngram: ngram, count: count, query: query } end.sort! { |record1, record2| record1[:count] <=> record2[:count] } diff --git a/spec/mongoid/criteria_search_spec.rb b/spec/mongoid/criteria_search_spec.rb index e07abb3..2e5b8ff 100644 --- a/spec/mongoid/criteria_search_spec.rb +++ b/spec/mongoid/criteria_search_spec.rb @@ -1,4 +1,4 @@ -# coding: utf-8 + require 'spec_helper' describe Mongoid::FullTextSearch do diff --git a/spec/mongoid/sci_search_spec.rb b/spec/mongoid/sci_search_spec.rb index aacb07a..2b40e66 100644 --- a/spec/mongoid/sci_search_spec.rb +++ b/spec/mongoid/sci_search_spec.rb @@ -1,4 +1,4 @@ -# coding: utf-8 + require 'spec_helper' describe Mongoid::FullTextSearch do From d0a26ad9bef7b415e6059262c40826cddf95946c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Tue, 8 May 2018 15:56:07 +0200 Subject: [PATCH 63/67] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 862e0fe..15d0013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ### 0.8.3 (Next) -* [#35](https://github.com/mongoid/mongoid_fulltext/pull/35): Mongoid 7 compatibility - [@tomasc](https://github.com/tomasc). +* [#37](https://github.com/mongoid/mongoid_fulltext/pull/37): Sci & criteria support - [@tomasc](https://github.com/tomasc). * Your contribution here. ### 0.8.2 (8/5/2018) From f48d76d01a0652b67a0b81b9b90e131e6c850b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Tue, 8 May 2018 15:57:11 +0200 Subject: [PATCH 64/67] use class attr --- lib/mongoid/full_text_search.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index efd569c..1730e2c 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -304,7 +304,7 @@ def update_ngram_index def document_type_filters return {} unless fields['_type'].present? kls = ([self] + descendants).map(&:to_s) - { 'document_type' => { '$in' => kls } } + { 'class' => { '$in' => kls } } end # Take a list of filters to be mapped so they can update the query @@ -361,7 +361,7 @@ def update_ngram_index end # insert new ngrams in external index ngrams.each_pair do |ngram, score| - index_document = { 'ngram' => ngram, 'document_id' => _id, 'document_type' => model_name.to_s, 'score' => score, 'class' => self.class.name } + index_document = { 'ngram' => ngram, 'document_id' => _id, 'score' => score, 'class' => self.class.name } index_document['filter_values'] = filter_values if fulltext_config.key?(:filters) if Mongoid::Compatibility::Version.mongoid5_or_newer? coll.insert_one(index_document) From 9f7e02c166bb6458ab3d52c305a9c8118029749b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Tue, 8 May 2018 15:59:22 +0200 Subject: [PATCH 65/67] require --- spec/models/my_further_inherited_doc.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/models/my_further_inherited_doc.rb b/spec/models/my_further_inherited_doc.rb index 2184c03..42f14e7 100644 --- a/spec/models/my_further_inherited_doc.rb +++ b/spec/models/my_further_inherited_doc.rb @@ -1,2 +1,4 @@ +require 'models/my_inherited_doc.rb' + class MyFurtherInheritedDoc < MyInheritedDoc end From 5e4bfa68e1ba2c7121ccfa43f62474d8a8d9a033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Tue, 8 May 2018 16:11:48 +0200 Subject: [PATCH 66/67] Merge branch 'sci-support' into localized-fields --- .rubocop_todo.yml | 12 ++++++------ lib/mongoid/full_text_search.rb | 2 +- spec/mongoid/localized_fields_spec.rb | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index b31254d..fcb1d8e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2018-05-08 15:36:14 +0200 using RuboCop version 0.55.0. +# on 2018-05-08 16:11:28 +0200 using RuboCop version 0.55.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -21,7 +21,7 @@ Layout/EndAlignment: Exclude: - 'lib/mongoid/full_text_search.rb' -# Offense count: 1 +# Offense count: 2 # Configuration parameters: AllowSafeAssignment. Lint/AssignmentInCondition: Exclude: @@ -43,11 +43,11 @@ Lint/UselessAssignment: Exclude: - 'spec/mongoid/full_text_search_spec.rb' -# Offense count: 5 +# Offense count: 7 Metrics/AbcSize: Max: 104 -# Offense count: 7 +# Offense count: 8 # Configuration parameters: CountComments, ExcludedMethods. Metrics/BlockLength: Max: 622 @@ -64,7 +64,7 @@ Metrics/MethodLength: # Offense count: 1 # Configuration parameters: CountComments. Metrics/ModuleLength: - Max: 300 + Max: 243 # Offense count: 4 Metrics/PerceivedComplexity: @@ -129,7 +129,7 @@ Style/NumericPredicate: - 'spec/**/*' - 'lib/mongoid/full_text_search.rb' -# Offense count: 265 +# Offense count: 269 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index 7d1d4e1..d2b9d1c 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -377,7 +377,7 @@ def update_ngram_index filter_values = Hash[fulltext_config[:filters].map do |key, value| begin [key, value.call(self)] - rescue + rescue StandardError # Suppress any exceptions caused by filters end end.compact] diff --git a/spec/mongoid/localized_fields_spec.rb b/spec/mongoid/localized_fields_spec.rb index 2cf46a8..a5398bc 100644 --- a/spec/mongoid/localized_fields_spec.rb +++ b/spec/mongoid/localized_fields_spec.rb @@ -1,9 +1,9 @@ -# coding: utf-8 + require 'spec_helper' describe Mongoid::FullTextSearch do context 'Localized fields' do - let!(:my_doc) { MyLocalizedDoc.create!(title_translations: { en: 'Title', cs: "Nazev" }) } + let!(:my_doc) { MyLocalizedDoc.create!(title_translations: { en: 'Title', cs: 'Nazev' }) } before(:each) do @default_locale = ::I18n.locale @@ -16,14 +16,14 @@ context 'en' do let(:locale) { :en } - it { expect(MyLocalizedDoc.fulltext_search("title")).to include my_doc } - it { expect(MyLocalizedDoc.fulltext_search("nazev")).not_to include my_doc } + it { expect(MyLocalizedDoc.fulltext_search('title')).to include my_doc } + it { expect(MyLocalizedDoc.fulltext_search('nazev')).not_to include my_doc } end context 'cs' do let(:locale) { :cs } - it { expect(MyLocalizedDoc.fulltext_search("title")).not_to include my_doc } - it { expect(MyLocalizedDoc.fulltext_search("nazev")).to include my_doc } + it { expect(MyLocalizedDoc.fulltext_search('title')).not_to include my_doc } + it { expect(MyLocalizedDoc.fulltext_search('nazev')).to include my_doc } end end end From aafd2ab8d95a3159a1400157eccdaf9050d9ce75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=CC=81s=CC=8C=20Celizna?= Date: Tue, 8 May 2018 16:17:39 +0200 Subject: [PATCH 67/67] add available locales --- spec/spec_helper.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a01760d..3d5c94e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,6 +22,8 @@ config.connect_to('mongoid_fulltext_test') end +::I18n.available_locales = %i[en cs] + RSpec.configure do |c| c.before :each do DatabaseCleaner.clean