From e0b499d29fb2effc9abc84278fb7dbc962a30db9 Mon Sep 17 00:00:00 2001 From: "Daniel (dB.) Doubrovkine" Date: Fri, 16 Oct 2026 22:45:06 -0400 Subject: [PATCH] Create full-text indexes before enumerating missing collections Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .rubocop_todo.yml | 25 ++----------------------- CHANGELOG.md | 1 + README.md | 2 ++ lib/mongoid/full_text_search.rb | 15 ++++++++------- spec/mongoid/full_text_search_spec.rb | 14 ++++++++++++++ 5 files changed, 27 insertions(+), 30 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 92aa111..4c8f44e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2026-10-17 02:30:37 UTC using RuboCop version 1.92.0. +# on 2026-10-17 03:01:17 UTC using RuboCop version 1.92.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 @@ -58,7 +58,7 @@ Metrics/AbcSize: # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. # AllowedMethods: refine Metrics/BlockLength: - Max: 632 + Max: 644 # Offense count: 5 # Configuration parameters: AllowedMethods, AllowedPatterns. @@ -129,19 +129,6 @@ Style/FormatString: Style/FormatStringToken: EnforcedStyle: unannotated -# Offense count: 30 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: always, always_true, never -Style/FrozenStringLiteralComment: - Enabled: false - -# Offense count: 1 -# This cop supports unsafe autocorrection (--autocorrect-all). -Style/HashTransformValues: - Exclude: - - 'lib/mongoid/full_text_search.rb' - # Offense count: 2 Style/MultilineBlockChain: Exclude: @@ -163,14 +150,6 @@ Style/OptionalBooleanParameter: Exclude: - 'lib/mongoid/full_text_search.rb' -# Offense count: 3 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength. -# AllowedMethods: present?, blank?, presence, try, try! -Style/SafeNavigation: - Exclude: - - 'lib/mongoid/full_text_search.rb' - # Offense count: 1 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments. diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c74c5f..5fde937 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ### 0.8.3 (Next) * [#59](https://github.com/mongoid/mongoid_fulltext/pull/59): Document and cover class-level indexing timeout options - [@dblock](https://github.com/dblock). +* [#52](https://github.com/mongoid/mongoid_fulltext/pull/52): Fix full-text index creation before any documents exist - [@dblock](https://github.com/dblock). * [#51](https://github.com/mongoid/mongoid_fulltext/pull/51): Modernize CI through Ruby 4.0, Mongoid 9, and MongoDB 8 with real coverage, RuboCop 1.92, and fork-safe Danger workflows - [@dblock](https://github.com/dblock). * [#45](https://github.com/mongoid/mongoid_fulltext/pull/45): Allow for class level ngram updates to not timeout - [@roykolak](https://github.com/roykolak). * Your contribution here. diff --git a/README.md b/README.md index 1efbe1f..662a002 100644 --- a/README.md +++ b/README.md @@ -256,6 +256,8 @@ Indexing Options `Artwork.update_ngram_index(timeout: false)` rebuilds the index for all records without a cursor timeout; the `timeout` option belongs to the class method, not the per-document `artwork.update_ngram_index` method. +`Artwork.create_indexes` can create the full-text collections and their indexes before any artworks have been saved. + Additional indexing/query options can be used as parameters to `fulltext_search_in`. * `alphabet`: letters to index, default is `abcdefghijklmnopqrstuvwxyz0123456789 `. diff --git a/lib/mongoid/full_text_search.rb b/lib/mongoid/full_text_search.rb index b5c4f59..5b749bf 100644 --- a/lib/mongoid/full_text_search.rb +++ b/lib/mongoid/full_text_search.rb @@ -79,6 +79,14 @@ def fulltext_search_ensure_indexes(index_name, config) db = collection.database coll = db[index_name] + # Creating an index also creates the collection before older drivers list its indexes. + Mongoid.logger.info "Ensuring document_id index on #{coll.name}" if Mongoid.logger + if Mongoid::Compatibility::Version.mongoid5_or_newer? + coll.indexes.create_one('document_id' => 1) + else + coll.indexes.create('document_id' => 1) + end + # The order of filters matters when the same index is used from two or more collections. filter_indexes = (config[:filters] || []).map do |key, _value| ["filter_values.#{key}", 1] @@ -116,13 +124,6 @@ def fulltext_search_ensure_indexes(index_name, config) 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_or_newer? - coll.indexes.create_one('document_id' => 1) # to make removes fast - else - coll.indexes.create('document_id' => 1) # to make removes fast - end end def fulltext_search(query_string, options = {}) diff --git a/spec/mongoid/full_text_search_spec.rb b/spec/mongoid/full_text_search_spec.rb index 070ba99..3278c41 100644 --- a/spec/mongoid/full_text_search_spec.rb +++ b/spec/mongoid/full_text_search_spec.rb @@ -657,6 +657,20 @@ end end + context 'creating indexes before any documents exist' do + it 'creates both indexes in a missing collection without inserting documents' do + coll = BasicArtwork.collection.database[BasicArtwork.mongoid_fulltext_config.keys.first] + BasicArtwork.create_indexes + coll.drop + BasicArtwork.create_indexes + + indexes = [] + coll.indexes.each { |index| indexes << index['name'] } + expect(indexes).to include('fts_index', 'document_id_1') if Mongoid::Compatibility::Version.mongoid5_or_newer? + expect(coll.find.count).to eq(0) + end + end + # For =~ operator documentation # https://github.com/dchelimsky/rspec/blob/master/lib/spec/matchers/match_array.rb#L53