Lọc kết quả bằng cách sử dụng THÍCH


16

Hãy xem xét ba chuỗi "haystack" này:

a) foo bar

b) welcome to foo bar industries

c) foo barer

Và bây giờ "kim" của tôi:

foo bar

(Heh)

Tôi muốn bộ lọc của mình khớp kim của tôi với chuỗi haystack a & b nhưng không phải c. Tôi đã thử:

$collection->addAttributeToFilter('name', array('like' => '%'.$needle.'%'));

Nhưng các trận đấu trên với c.

Tôi cũng đã thử:

$collection->addAttributeToFilter('name', array('like' => '% '.$needle.' %')); // Note the spaces

Ở trên chỉ phù hợp với b.

Bất kỳ sự giúp đỡ nào cũng được đánh giá cao.

Câu trả lời:


37

Hãy dùng thử và xem nó có phù hợp không:

$collection->addAttributeToFilter('name', array(
    array('like' => '% '.$needle.' %'), //spaces on each side
    array('like' => '% '.$needle), //space before and ends with $needle
    array('like' => $needle.' %') // starts with needle and space after
));

Truyền tham số thứ hai dưới dạng một mảng các mảng sẽ ghép các điều kiện bằng cách sử dụng OR


Điều đó hoạt động :) Không biết về thủ thuật mảng, cảm ơn.
Beingalex

Với các mô hình tùy chỉnh / không phải là eav addAttributeToFilternên được thay thế bằng addFieldToFilter.
jvalanen

Có cách nào để xác định mảng nào trả về kết quả không? Tôi đang sử dụng phương pháp này để tìm kiếm bộ sưu tập mô hình tùy chỉnh (tên, mô tả, trường xen kẽ) và tôi muốn biết liệu kết quả có bị đánh vì mô tả hay không (để bao gồm phần tử UI bổ sung vào kết quả tìm kiếm).
pspahn

3
@pspahn Không phải là một chuyển tiếp thẳng. Bạn có thể lặp qua các kết quả sau khi lựa chọn được thực thi và kiểm tra xem kim có được tìm thấy trong bất kỳ trường nào bạn muốn không.
Marius

9

Một giải pháp có thể là sử dụng REGEXPthay vì LIKE:

$collection->addAttributeToFilter('name', array('regexp' => '[[:<:]]'.$needle.'[[:>:]]'));

Từ tài liệu MySQL :

[[: <:]], [[:>:]]

Những điểm đánh dấu là viết tắt của ranh giới từ. Chúng phù hợp với đầu và cuối của từ tương ứng. Một từ là một chuỗi các ký tự từ không có trước hoặc theo sau bởi các ký tự từ. Một ký tự từ là một ký tự chữ và số trong lớp alnum hoặc dấu gạch dưới (_).

Lưu ý rằng nếu $needlecó thể chứa các ký tự có ý nghĩa đặc biệt trong biểu thức chính quy POSIX, bạn cần thoát chúng. Xem thêm: /programming/4024188/php-feft-to-escape-mysql-regapid-syntax


3

Câu trả lời được chấp nhận không hoạt động đúng. Nó chỉ kiểm tra không gian trước và sau văn bản.

Giả sử, bạn có danh sách sau đây

  • Áo khoác
  • Áo khoác mùa hè
  • Áo khoác mùa đông

Bây giờ nếu bạn cố gắng tìm kiếm với áo khoác bằng câu trả lời được chấp nhận, nó sẽ chỉ trả về Áo khoác mùa hèÁo khoác mùa đông

Tôi nghĩ rằng giải pháp sau là tốt hơn

$collection->addAttributeToFilter('name', array('like' => '%' . $needle. '%'));

Nó sẽ không bao gồm trường hợp (c) từ câu hỏi (nghĩa là cũng khớp với "áo khoác"). Thay vào đó, một điều kiện thứ tư ['eq' => $needle]có thể được thêm vào để tìm các kết quả khớp chính xác (hoặc tốt hơn, sử dụng giải pháp regex tìm tất cả các ranh giới, không chỉ các khoảng trắng)
Fabian Schmengler 29/03/18

ở trên mã có thể tìm thấy các kết hợp chính xác. Tôi đã kiểm tra nó
Dinesh Yadav

Tôi không nghi ngờ điều đó. Nhưng nó tìm thấy nhiều hơn, mà nó không nên. Ít nhất nếu bạn có các yêu cầu giống như trong câu hỏi ban đầu: Không tìm thấy "foo barer" khi tìm kiếm "foo bar"
Fabian Schmengler 29/03/18

Vâng, bạn đúng. Câu trả lời được chấp nhận không hoạt động đúng với tôi vì vậy tôi đã đề xuất bộ lọc một dòng đơn giản để nhận các mục tương tự.
Dinesh Yadav
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.