Searchkick ไม่ค้นหาหลายคำเมื่อระบุฟิลด์

ใครสามารถให้คำแนะนำในเรื่องต่อไปนี้โปรด?

ฉันใช้ searchkick / elasticsearch และต้องการค้นหาคำสำคัญหรือคำในหลายฟิลด์ (ชื่อ ผู้ผลิต) ตัวอย่างเช่น หากฉันกำลังค้นหาผลิตภัณฑ์ชื่อ "myproduct" ทำให้ "ผู้ผลิตบางราย" ของฉัน ฉันคาดหวังว่าจะเห็นผลลัพธ์นี้ปรากฏขึ้นหากฉันค้นหา "myproduct", "somemanufacturer" หรือ "myproduct somemanufacturer" เนื่องจากทั้งสองคำนี้รวมอยู่ด้วย ในฟิลด์ชื่อหรือผู้ผลิต

ปัญหาของฉันมีดังต่อไปนี้:

@products = Product.search query

อนุญาตคำค้นหาทั้งหมดที่แสดงไว้ด้านบนและส่งกลับผลลัพธ์ที่คาดหวังทันทีที่ฉันเพิ่ม

@products = Product.search query, fields: [:name, :manufacturer_name]

โดยจะส่งกลับผลลัพธ์สำหรับ "myproduct" หรือ "somecompany" เท่านั้น แต่จะไม่ส่งคืน "myproduct somecompany"

ตอนนี้ไม่ใช่เรื่องใหญ่เนื่องจากฉันสามารถลบตัวเลือกฟิลด์ทั้งหมดได้ แต่ฉันต้องใช้ searchkicks word_start สำหรับฟิลด์ชื่อ ดังนั้นคำถามสุดท้ายของฉันจึงเป็นดังนี้:

@products = Product.search query, fields: [{name: :word_start}, :manufacturer_name]

ฉันต้องการให้ผู้ใช้ค้นหาสตริงที่ 1 ของผลิตภัณฑ์และสามารถป้อนผู้ผลิตได้เช่นกัน เช่น "myprod somecompany" น่าเสียดายที่สิ่งนี้ส่งคืนผลลัพธ์เป็นศูนย์เมื่อฉันหวังว่ามันจะส่งคืนผลิตภัณฑ์ชื่อ myproduct ซึ่งผลิตโดย somecompany

ฉันพลาดบางสิ่งที่ชัดเจนที่นี่ไปหรือเปล่า? เปลี่ยนเพิ่มได้นะครับ

operator: 'or'

แต่จริงๆ แล้ว ฉันต้องการที่จะแยกการค้นหาชื่อ เพิ่มคำศัพท์เพิ่มเติม และหากทั้งสองรายการปรากฏสำหรับบันทึกใดรายการหนึ่ง ก็จะถูกส่งกลับ

นี่คือรหัสรุ่นของฉันด้วย

class Product < ActiveRecord::Base
 searchkick word_start: [:name]
end

ขอบคุณ


person drac    schedule 23.09.2015    source แหล่งที่มา
comment
ฉันมีปัญหาเดียวกันนี้ คุณทราบไหม?   -  person William Weckl    schedule 11.12.2015
comment
คิดออกโพสต์เป็นคำตอบ   -  person William Weckl    schedule 14.12.2015


คำตอบ (2)


หากฟิลด์ทั้งหมดของคุณใช้ตัววิเคราะห์เดียวกัน คุณสามารถใช้คุณลักษณะ elasticsearch ที่เรียกว่า cross_fields ได้ หากไม่เป็นเช่นนั้น คุณสามารถใช้ query_string ได้ ขออภัย searchkick ยังไม่รองรับ cross_fields และ query_string ดังนั้นคุณต้องทำด้วยตัวเอง

ดัชนี (ตัววิเคราะห์ที่แตกต่างกัน)

searchkick merge_mappings: true, mappings: {
  product: {
    properties: {
      name: {
        type: 'string',
        analyzer: 'searchkick_word_start_index',
        copy_to: 'grouped'
      },
      manufacturer_name: {
        type: 'string',
        analyzer: 'default_index',
        copy_to: 'grouped'
      },
      grouped: {
        raw: {type: 'string', index: 'not_analyzed'}
      }
    }
  }
}

ค้นหาด้วย cross_fields

@products = Product.search(body: {
  query: {
     multi_match: {
                  query: query,
                  type: "cross_fields",
                  operator: "and",
                  fields: [
                      "name",
                      "manufacturer_name",
                      "grouped",
                  ]
              }
         }
}

ค้นหาด้วย query_string

@products = Product.search(body: {
  query: {
      query_string: {
                  query: query,
                  default_operator: "AND",
                  fields: [
                      "name",
                      "manufacturer_name",
                      "grouped",
                  ]
              }
         }
}

อัปเดต - เปลี่ยนคำตอบของฉันเป็นการใช้ตัววิเคราะห์ที่แตกต่างกันและหลายฟิลด์ตามโซลูชันนี้

น่าเสียดายที่การส่งคำค้นหาไปที่ elasticsearch ด้วยตัวเอง คุณจะสูญเสียคุณลักษณะ searchkick เช่น ไฮไลต์และ Conversion ออกไป แต่คุณยังคงสามารถทำได้ โดยเพิ่มลงในคำค้นหา elasticsearch

การเพิ่มไฮไลต์ให้กับข้อความค้นหา

@products = Product.search(body: {
  query: {
    ...
  }, highlight: {
    fields: {
      name: {},
      manufacturer_name: {}
    }
  }

การเพิ่ม Conversion ให้กับข้อความค้นหา

@products = Product.search(body: {
  query: {
    bool: {
      must: {
        dis_max: {
          queries: {
            query_string: {
              ...
            }
          }
        }
      },
      should: {
        nested: {
          path: 'conversions',
          score_mode: 'sum',
          query: {
            function_score: {
              boost_mode: 'replace',
              query: {
                match: {
                  "conversions.query": query
                }
              },
              field_value_factor: {
                field: 'conversions.count'
              }
            }
          }
        }
      }
    }
  }
person William Weckl    schedule 14.12.2015
comment
คุณได้ 'searchkick_word_start_index' และ 'default_index' มาจากไหน??? - person Deez Nuuts; 28.06.2019

วิธีที่ง่ายที่สุดในการดำเนินการนี้คือการรวมช่องต่างๆ ให้เป็นช่องเดียวโดยใช้วิธี search_data

class Product
  def search_data
    {
      full_name: "#{manufacturer_name} #{name}"
    }
  end
end

อย่าลืมจัดทำดัชนีใหม่ในภายหลัง จากนั้นใช้ชื่อเต็มในการค้นหา คุณลักษณะทั้งหมดของ Searchkick จะยังคงทำงานต่อไป

person Andrew Kane    schedule 10.08.2018