Динамически добавлять данные в карту JavaScript

Я выяснил, что расстояние Левенштейна может быть хорошим, когда вы ищете полную строку против другой полной строки, но когда вы ищете ключевые слова в строке, этот метод не возвращает (иногда) желаемые результаты. Кроме того, функция SOUNDEX не подходит для языков, отличных от английского, поэтому она весьма ограничена. Вы можете уйти с LIKE, но это действительно для базовых поисков. Вы можете захотеть взглянуть на другие методы поиска того, чего вы хотите достичь. Например:

Вы можете использовать Lucene в качестве базы поиска для ваших проектов. Он реализован на большинстве основных языков программирования, и он будет довольно быстрым и универсальным. Этот метод, вероятно, лучший, поскольку он не только ищет подстроки, но и транспонирование, префиксы и суффиксы букв (все вместе). Тем не менее, вам нужно сохранить отдельный индекс (используя CRON для обновления его из независимого скрипта раз в то время как работает хотя).

Или, если вы хотите решение MySQL, полнотекстовая функциональность довольно хороша, и, конечно, быстрее, чем хранимая процедура. Если ваши таблицы не являются MyISAM, вы можете создать временную таблицу, а затем выполнить полнотекстовый поиск:

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 ;

Используйте генератор данных , чтобы сгенерировать некоторые случайные данные, t хотите самим создать его ...

** ПРИМЕЧАНИЕ **: тип столбца должен быть latin1_bin, чтобы выполнить поиск с учетом регистра, а не регистр, нечувствительный к latin1. Для строк unicode я рекомендовал бы utf8_bin для чувствительности к регистру и utf8_general_ci для поиска без учета регистра.

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

Недостатком этого является то, что он не будет искать транспонирование букв или «похожие, звуковые слова».

** ОБНОВЛЕНИЕ **

Использование Lucene для в вашем поиске вам просто нужно создать задание cron (все веб-хосты имеют эту «функцию»), где это задание будет просто исполнять скрипт PHP (ig «cd / path / to / script; php searchindexer.php»), который будет обновить индексы. Причина в том, что индексирование тысяч «документов» (строк, данных и т. Д.) Может занять несколько секунд, даже минут, но это необходимо для того, чтобы все поисковые запросы выполнялись как можно быстрее. Поэтому вам может потребоваться создать задание задержки, которое будет выполняться сервером. Это может быть на ночь, или в следующий час, это зависит от вас. PHP-скрипт должен выглядеть примерно так:

$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

Тогда это в основном то, как вы ищите (основной поиск):

$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.
}

Вот отличные сайты о Lucene в Java , PHP и .Net .

В заключение у каждого метода поиска есть свои плюсы и минусы:

  • Вы упомянули Sphinx search , и он выглядит очень хорошо, если вы можете заставить деамона работать на вашем веб-хосте.
  • Zend Lucene требует задания cron для повторной индексации базы данных. Хотя это совершенно прозрачно для пользователя, это означает, что любые новые данные (или удаленные данные!) Не всегда синхронизируются с данными в вашей базе данных и поэтому не будут отображаться сразу при поиске пользователей.
  • Поиск MySQL FULLTEXT хорош и быстр, но не даст вам всей силы и гибкости первых двух.

Пожалуйста, не стесняйтесь комментировать, если я что-то забыл / пропустил.

54
задан Brian Tompsett - 汤莱恩 12 November 2015 в 12:02
поделиться

1 ответ

Ну, любой объект Javascript функционирует как «карта»

randomObject['hello'] = 'world';

Обычно люди создают для этой цели простые объекты:

var myMap = {};

// ...

myMap[newKey] = newValue;

edit - ну, проблема с явным Функция "put" заключается в том, что вам придется приложить все усилия, чтобы сама функция не выглядела как часть карты. На самом деле это не относится к Javascripty.

13 февраля 2014 г. - современный JavaScript имеет средства для создания свойств объекта, которые не перечисляются, и это довольно легко сделать. Тем не менее, все еще имеет место случай, когда свойство «put», перечислимое или нет, будет требовать имя свойства «put» и сделать его недоступным. То есть для каждого объекта по-прежнему существует только одно пространство имен.

104
ответ дан 24 November 2019 в 19:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: