You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
1.7 KiB

  1. # frozen_string_literal: true
  2. class TagSearchService < BaseService
  3. def call(query, options = {})
  4. @query = query.strip.gsub(/\A#/, '')
  5. @offset = options.delete(:offset).to_i
  6. @limit = options.delete(:limit).to_i
  7. @options = options
  8. results = from_elasticsearch if Chewy.enabled?
  9. results ||= from_database
  10. results
  11. end
  12. private
  13. def from_elasticsearch
  14. query = {
  15. function_score: {
  16. query: {
  17. multi_match: {
  18. query: @query,
  19. fields: %w(name.edge_ngram name),
  20. type: 'most_fields',
  21. operator: 'and',
  22. },
  23. },
  24. functions: [
  25. {
  26. field_value_factor: {
  27. field: 'usage',
  28. modifier: 'log2p',
  29. missing: 0,
  30. },
  31. },
  32. {
  33. gauss: {
  34. last_status_at: {
  35. scale: '7d',
  36. offset: '14d',
  37. decay: 0.5,
  38. },
  39. },
  40. },
  41. ],
  42. boost_mode: 'multiply',
  43. },
  44. }
  45. filter = {
  46. bool: {
  47. should: [
  48. {
  49. term: {
  50. reviewed: {
  51. value: true,
  52. },
  53. },
  54. },
  55. {
  56. match: {
  57. name: {
  58. query: @query,
  59. },
  60. },
  61. },
  62. ],
  63. },
  64. }
  65. definition = TagsIndex.query(query)
  66. definition = definition.filter(filter) if @options[:exclude_unreviewed]
  67. definition.limit(@limit).offset(@offset).objects.compact
  68. rescue Faraday::ConnectionFailed, Parslet::ParseFailed
  69. nil
  70. end
  71. def from_database
  72. Tag.search_for(@query, @limit, @offset, @options)
  73. end
  74. end