SORU
26 Temmuz 2010, PAZARTESİ


Nasıl benzer sonuçları bulmak ve benzerliklerine göre sıralamak için?

Nasıl kayıt benzerlik ile sipariş için sorgu?

Örn. "Hisse senedi Taşması" döndürecektir . aranıyor

  1. Yığın Taşması
  2. SharePoint Taşması
  3. Matematik Taşması
  4. Politik Taşması
  5. EFEKT Taşması

Örn. "LO" olurdu geri: arıyorum

  1. pabLO picasso
  2. michelangeLO
  3. jackson polLOck

Ne ben yardım edeyim:

  1. Dizin ve arama için bir arama motoru MySQL bir tablo kullanarak, daha iyi sonuçlar için

    • Sphinx arama motoru, PHP ile kullanarak

    • PHP ile Lucene motoru kullanarak

  2. Tam metin dizin oluşturma kullanarak, benzer/içeren dizeleri bulmak için


Peki ne işe yaramazsa

  • Levenshtein distance çok düzensiz.. (UDF, Query)
    "Köpek" bana verir:arama
    1. köpek
    2. bataklık
    3. önce
    4. büyük
    5. echo
  • LIKE daha iyi sonuç verir, ama benzer dizeleri de var olsa da uzun sorgular için hiçbir şey döndürür
    1. köpek
    2. dogid
    3. dogaral
    4. dogma

CEVAP
26 Temmuz 2010, PAZARTESİ


Ben öğrendim Levenshtein mesafe olabilir iyi de o zaman arama bir tam dize karşı tam bir dize, ama ne zaman sen are seyir için anahtar kelime içinde bir string bu yöntem geri dönüşü yok (bazen) aranıyor sonuçları. Ayrıca, SOUNDEX işlevi oldukça sınırlı bu yüzden İngilizce dışındaki diller için uygun değildir. GİBİ uzağa gidebilirsin, ama gerçekten basit aramalar için. Elde etmek istediğiniz şey için diğer arama yöntemleri içine bakmak isteyebilirsiniz. Örneğin:

Projeleriniz için arama üs olarak Lucene kullanabilirsiniz. En büyük programlama dilinde uygulanan ve oldukça hızlı ve çok yönlü. Bu yöntem sadece dizeleri, ama aynı zamanda mektup hukuka, önek ve sonek (hep birlikte) için arama olarak en iyisi. Ancak, ayrı bir dizin (CRON bir süre işe yarar ama bir zamanlar bağımsız bir script update kullanarak) tutmak gerekir.

Ya da, eğer MySQL bir çözüm istiyorsanız, tam metin işlevselliği oldukça iyi, ve bir saklı yordam daha kesinlikle daha hızlı. Eğer tablolarınız hali hazırda hiç değilse, geçici bir tablo oluşturmak, full-text arama gerçekleştirin

CREATE TABLE IF NOT EXISTS `tests`.`data_table` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(2000) CHARACTER SET latin1 NOT NULL,
  `description` text CHARACTER SET latin1 NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;

Eğer kendiniz yaratmak rahatsız etmek istemezsin Eğer hala kullanmak bir rastgele veri oluşturmak için data generator...

**NOT** : sütun tipi latin1_bin dava latin1 büyük / küçük harf duyarlı yerine duyarlı bir arama gerçekleştirmek için olmalıdır. Unicode dizeleri için, dava için utf8_bin duyarsız aramalarda büyük / küçük harf duyarlı ve utf8_general_ci tavsiye ederim.

DROP TABLE IF EXISTS `tests`.`data_table_temp`;
CREATE TEMPORARY TABLE `tests`.`data_table_temp`
   SELECT * FROM `tests`.`data_table`;

ALTER TABLE `tests`.`data_table_temp`  ENGINE = MYISAM;

ALTER TABLE `tests`.`data_table_temp` ADD FULLTEXT `FTK_title_description` (
  `title` ,
  `description`
);

SELECT *,
       MATCH (`title`,`description`)
       AGAINST (' so*  nullam lorem' IN BOOLEAN MODE) as `score`
  FROM `tests`.`data_table_temp`
 WHERE MATCH (`title`,`description`)
       AGAINST (' so*  nullam lorem' IN BOOLEAN MODE)
 ORDER BY `score` DESC;

DROP TABLE `tests`.`data_table_temp`;

MySQL API reference page dan hakkında daha fazla bilgi edinin

Bunun eksisi mektup aktarılması ya da "kelime" gibi. benzer sesler için görünür değil

**GÜNCELLEME**

Arama için Lucene kullanarak, sadece bir cron işi oluşturmak için ihtiyacınız olacak (tüm web barındıran bu var bu iş sadece PHP bir script çalıştırır"") özelliği (ben.g. "/yol/cd/script; php searchindexer.php") bu dizinleri günceller. Bu nedenle indeksleme binlerce "belgeler" (satır, veri, vb.) birkaç saniye, hatta birkaç dakika sürebilir, ama bu tüm aramalara mümkün olduğunca hızlı bir şekilde yapıldığından emin olmak. Bu nedenle, sunucu tarafından çalıştırılacak gecikme bir iş oluşturmak isteyebilirsiniz. Bir gecede olabilir, ya da bir saat içinde, bu sana kalmış. PHP komut dosyası gibi bir şey görünmelidir

$indexer = Zend_Search_Lucene::create('/path/to/lucene/data');

Zend_Search_Lucene_Analysis_Analyzer::setDefault(
  // change this option for your need
  new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive()
);

$rowSet = getDataRowSet();  // perform your SQL query to fetch whatever you need to index
foreach ($rowSet as $row) {
   $doc = new Zend_Search_Lucene_Document();
   $doc->addField(Zend_Search_Lucene_Field::text('field1', $row->field1, 'utf-8'))
       ->addField(Zend_Search_Lucene_Field::text('field2', $row->field2, 'utf-8'))
       ->addField(Zend_Search_Lucene_Field::unIndexed('someValue', $someVariable))
       ->addField(Zend_Search_Lucene_Field::unIndexed('someObj', serialize($obj), 'utf-8'))
  ;
  $indexer->addDocument($doc);
}

// ... you can get as many $rowSet as you want and create as many documents
// as you wish... each document doesn't necessarily need the same fields...
// Lucene is pretty flexible on this

$indexer->optimize();  // do this every time you add more data to you indexer...
$indexer->commit();    // finalize the process

Sonra, bu temelde nasıl arama (basit arama) :

$index = Zend_Search_Lucene::open('/path/to/lucene/data');

// same search options
Zend_Search_Lucene_Analysis_Analyzer::setDefault(
   new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive()
);

Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding('utf-8');

$query = 'php  field1:foo';  // search for the word 'php' in any field,
                                 //  search for 'foo' in field 'field1'

$hits = $index->find($query);

$numHits = count($hits);
foreach ($hits as $hit) {
   $score = $hit->score;  // the hit weight
   $field1 = $hit->field1;
   // etc.
}

Burada Java, PHP .Net Lucene hakkında harika siteler.

Sonuç olarakher arama yöntemleri kendi artıları ve eksileri var :

  • Sphynx search bahsetmiştin ve çok iyi, deamon web host üzerinde çalıştırmak mümkün olduğunca uzun görünüyor.
  • Zend Lucene yeniden dizin veritabanı için bir cron işi gerektirir. Kullanıcı için oldukça şeffaf olsa da, bu yeni veri (veya silinmiş verileri!) anlamına gelir verileri veritabanı ve bu nedenle ile her zaman uyumlu değildir hemen kullanıcı arama gösterilmez.
  • MySQL tam metin arama hızlı ve iyi, ama ilk iki tüm güç ve esneklik kazandıracak.

Lütfen eğer bir şey kaçırmış/unutursam yorum yapmaktan çekinmeyin.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • BetterCoder

    BetterCoder

    17 Aralık 2012
  • hitcreatormusic2

    hitcreatormu

    21 Mayıs 2010
  • LIVESTRONG.COM

    LIVESTRONG.C

    5 EKİM 2005