about summary refs log tree commit diff
path: root/app/chewy
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-02-09 23:04:47 +0100
committerGitHub <noreply@github.com>2018-02-09 23:04:47 +0100
commit3ebc0ad4d3c2fe0b0951a334642b769bd521a799 (patch)
tree9b88b2da41dbbc24cb922660937b5ee65366c38d /app/chewy
parent235c14c79d620d47012a08425324df222a136457 (diff)
Full-text search for authorized statuses (#6423)
* Add full-text search for authorized statuses

- Search API will return statuses that match the query
- Only for logged in users
- Only if you are author of the status,
- Or you were mentioned in it
- Or you favourited or reblogged it
- Configuration over `ES_ENABLED`, `ES_HOST`, `ES_PORT`, `ES_PREFIX`
- Run `rails chewy:deploy` to create & populate index

Fix #5880
Fix #4293
Fix #1152

* Add commented out docker-compose configuration for ES container

* Optimize index import, filter search results

* Add basic normalization to the index

* Add better stemming and normalization to the index

* Skip webfinger request if search query includes both @ and a space

* Fix code style

* Visually separate search result sections

* Fix code style issues
Diffstat (limited to 'app/chewy')
-rw-r--r--app/chewy/statuses_index.rb61
1 files changed, 61 insertions, 0 deletions
diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb
new file mode 100644
index 000000000..8bf5b4af7
--- /dev/null
+++ b/app/chewy/statuses_index.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+class StatusesIndex < Chewy::Index
+  settings index: { refresh_interval: '15m' }, analysis: {
+    filter: {
+      english_stop: {
+        type: 'stop',
+        stopwords: '_english_',
+      },
+      english_stemmer: {
+        type: 'stemmer',
+        language: 'english',
+      },
+      english_possessive_stemmer: {
+        type: 'stemmer',
+        language: 'possessive_english',
+      },
+    },
+    analyzer: {
+      content: {
+        tokenizer: 'uax_url_email',
+        filter: %w(
+          english_possessive_stemmer
+          lowercase
+          asciifolding
+          cjk_width
+          english_stop
+          english_stemmer
+        ),
+      },
+    },
+  }
+
+  define_type ::Status.without_reblogs do
+    crutch :mentions do |collection|
+      data = ::Mention.where(status_id: collection.map(&:id)).pluck(:status_id, :account_id)
+      data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
+    end
+
+    crutch :favourites do |collection|
+      data = ::Favourite.where(status_id: collection.map(&:id)).pluck(:status_id, :account_id)
+      data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
+    end
+
+    crutch :reblogs do |collection|
+      data = ::Status.where(reblog_of_id: collection.map(&:id)).pluck(:reblog_of_id, :account_id)
+      data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
+    end
+
+    root date_detection: false do
+      field :account_id, type: 'long'
+
+      field :text, type: 'text', value: ->(status) { [status.spoiler_text, Formatter.instance.plaintext(status)].join("\n\n") } do
+        field :stemmed, type: 'text', analyzer: 'content'
+      end
+
+      field :searchable_by, type: 'long', value: ->(status, crutches) { status.searchable_by(crutches) }
+      field :created_at, type: 'date'
+    end
+  end
+end