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.

82 lines
1.5 KiB

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