Knex: Dukungan untuk indeks pencarian teks lengkap

Dibuat pada 15 Mar 2014  ·  36Komentar  ·  Sumber: knex/knex

Postgres, sqlite, dan MySQL semuanya mendukung beberapa bentuk indeks teks lengkap. Akan berguna untuk mendukung pembuatan skema dan pembuatan kueri berdasarkan indeks ini.

Ini sepertinya bukan fitur yang sepele, karena implementasinya sangat berbeda untuk persyaratan pembuatan indeks (sqlite tampaknya berada di level tabel, MySQL hanya mendukungnya di tabel MyISAM) dan melakukan kueri.

Meskipun demikian, masalah ini setidaknya dapat digunakan untuk melacak minat terhadap fitur semacam itu.

Referensi:

Contoh pembuatan indeks dan pembuatan kueri:

  • PostgreSQL:
CREATE INDEX <INDEX NAME> ON <TABLE NAME> USING gin(to_tsvector(<COLUMN NAME>));

SELECT * FROM <TABLE NAME> WHERE <COLUMN NAME> @@ to_tsquery(<INPUT>);
  • MySQL:
CREATE FULLTEXT INDEX <INDEX NAME> ON <TABLE NAME>;

SELECT * FROM <TABLE NAME> WHERE MATCH <COLLUMN NAME> AGAINST <INPUT>;
  • sqlite:
CREATE VIRTUAL TABLE <TABLE> USING fts3(<COLUMN NAME> TEXT);

SELECT * FROM <TABLE NAME> WHERE <COLUMN NAME> MATCH <INPUT>;
feature request help wanted

Komentar yang paling membantu

menghapus banjir +1 dan komentar permintaan pembaruan status, silakan gunakan jempol untuk voting

EDIT: jika tidak ada pesan baru di feed ini, maka tidak ada yang baru untuk diceritakan

Semua 36 komentar

Diperbantukan tentu saja, saya pikir itu mungkin sudah didukung karena tampaknya agak penting.

Akan didukung dalam rilis minor berikutnya, saya syuting untuk akhir Maret untuk itu.

@tgriesser wow, itu tidak terduga tapi luar biasa. Terima kasih!

@tgriesser Apakah ini benar-benar terjadi?

Ini belum dirilis. Biarkan saya pergi dan pastikan ini ditambahkan, mencoba menutup hampir setiap tiket yang tersisa di sini dengan versi baru. Saya tahu Anda sekarang dapat mengganti nama kolom dan mengubah jenis :)

Oooooooh seru! : tada: cc / @sebgie

@ErisDS jadi saya melihat ini lagi, hanya ingin memastikan bagaimana saya berpikir tentang hal itu akan berhasil ... saya berpikir Anda akan melakukan t.text('colName').fulltext() atau t.fulltext(columnName) .. .hanya ingin memastikan bahwa Anda menyadari bahwa di sqlite3 Anda kehilangan kemampuan untuk melakukan pengindeksan lain pada tabel dan kemampuan untuk menambahkan kolom. Agaknya, fungsionalitas itu akan diinginkan, jadi saya harus menambahkannya ke sqlite3 ddl, tetapi hanya ingin menunjukkannya.

hanya ingin memastikan bahwa Anda sadar bahwa di sqlite3 Anda kehilangan kemampuan untuk melakukan pengindeksan lain di tabel dan kemampuan untuk menambahkan kolom. Agaknya, fungsionalitas itu akan diinginkan, jadi saya harus menambahkannya ke sqlite3 ddl, tetapi hanya ingin menunjukkannya.

Maksud Anda, Anda kehilangan kemampuan untuk menambahkan kolom secara normal, dan harus melakukan semua penyalinan tabel?

Ya. Tampaknya menjadi cerita dengan hampir semua hal seputar memodifikasi sqlite, kecuali sekarang bahkan menambahkan kolom.

Wooohoooooo: balon: ... lol

Di Ghost - akan ada penurunan harga posting, judul, dan mungkin nama tag yang ingin kita lakukan FTS. Saya pikir untuk memulai dengan ... tidak yakin apakah itu membantu.

Saya baru saja menemukan FULLTEXT ... MATCH di MySQL (inti yang seperti itu), menghabiskan satu jam mencoba memaksa fullText: function(name) { this.isFullText = name || true; return this; } ke SchemaBuilder kemudian mencoba memasukkannya ke SchemaGrammar tanpa scucess, lalu saya menemukan utas ini;)

Butuh dana untuk 0,6 @tgriesser? Saya tidak tahu bagaimana Anda sudah melakukan ini banyak :)

: +1:

@ tgriesser @ErisDS Untuk sqllite dan FTS mungkin mengikuti pola ini akan berhasil? http://peewee.readthedocs.org/en/latest/peewee/playhouse.html?highlight=full%20text#FTSModel Mereka membuat tabel terpisah khusus untuk digunakan dalam indeks pencarian teks lengkap. Dengan cara itu mereka menghindari mengubah semua kolom menjadi teks di tabel utama.

@dwstevens yang bisa berfungsi, tidak yakin di mana kita berada di FTS di sini. Rak buku mendukung plugin, mungkin hal seperti ini dapat dilakukan dengan plugin dan knex raw? Akan menjadi hal yang luar biasa bagi seseorang untuk bermain bersama dan melihat apakah mereka bisa mendapatkan versi yang berfungsi bersama.

Saya baru saja mengangkat masalah diskusi tentang Ghost tentang penerapan pencarian, itu terkait di sini . Ini benar-benar masalah tertua di repositori kami dan kami sangat perlu untuk melanjutkannya.

@tgriesser apa status di sini di knex? Apakah ada rencana? Kami benar-benar dapat menggunakan masukan Anda.

@ErisDS Solusi kami dengan Sequelize adalah menggunakan kueri Sequelize mentah untuk indeks FT kami. Sekarang saya mencoba untuk beralih ke pola DAO dan menggunakan Knex, saya kemungkinan akan mengimplementasikan sesuatu yang serupa. Ini tidak seanggun memiliki dukungan bawaan, tetapi itu akan berhasil.

@tgriesser Saya ingin membantu jika saya bisa!

@bomattin Saya rasa kebanyakan orang menggunakan kueri mentah, tetapi hanya harus mendukung satu DB, di mana kami perlu memiliki dukungan untuk Sqlite3, MySQL & pg. Apakah Anda berencana untuk menulis sesuatu yang digeneralisasikan?

@ErisDS Saya akan mulai memeriksanya. Sayangnya sebagian besar waktu pemrograman saya untuk minggu depan atau lebih akan membangun DAO saya dan mencoba menjual sesama pengembang di dalamnya. Saya melihat basis kode Knex ketika saya bisa sehingga saya dapat mencoba menyelami dan melakukannya dengan benar dengan cepat.

Halo! Ada keberuntungan dalam hal ini?

@ s-stude Sayangnya, tidak ada gerakan di pihak saya. Inilah yang saya gunakan untuk saat ini:

Users.find = function(params, options) {
    return new Promise(function(resolve, reject){
        var options = options? options : {};
        var whereclause;
        var lim = options.limit? options.limit : 65536; // Need a valid number here? 50 isn't a bad default.
        knex.select(cols.user)
            .from('users')
            .orWhereRaw('MATCH(firstname_preferred,lastname_preferred,username) AGAINST(? IN BOOLEAN MODE)', params.search)
            //.orWhereRaw('MATCH(groups.name) AGAINST(? IN BOOLEAN MODE)', '+matt*')
            .limit(lim)
            .then(function(userresults){
                resolve(new Users(userresults))
            })
            .catch(function(err){
                reject(err)
            });
    })
};

Ada pembaruan di sini?

Inilah yang saya gunakan sebagai solusi:

query.whereRaw('to_tsvector(parts.description) || to_tsvector(cars.engine_name)
        || to_tsvector(makes.name) || to_tsvector(models.name)
        || to_tsvector(part_types.name) || to_tsvector(part_types.description)
        || to_tsvector(part_categories.name)
        || to_tsvector(part_manufacturers.name) @@ to_tsquery(?)',req.query.search);

Saya melihat http://knexjs.org/#Schema -index dan melewatkan detail kecil tentang "tipe indeks hanya didukung di PostgreSQL", jadi saya menjalankan berikut ini sebagai bagian dari migrasi:

return knex.schema.table('host', t => {
  t.index('name', 'name_idx', 'FULLTEXT') # <<< I wish
})

menghasilkan .debug() output terhadap mysql:

[ { sql: 'alter table `host` add index name_idx(`name`)',
    bindings: [] } ]

di mana saya kira seharusnya mengatakan add FULLTEXT index ... Apakah ada sesuatu yang secara khusus memblokir argumen Type agar tidak digunakan untuk dialek mysql?

Apa yang terjadi dengan ini? Apakah ada perampokan? Bisakah saya membantu?

@yamikuronue yakin, sepertinya database besar mendukung ini, jadi API umum untuk membuat index alangkah baiknya. Permintaan tarik diterima jika Anda ingin menerapkan ini.

Apakah ada pekerjaan yang sudah selesai yang dapat saya kembangkan, atau haruskah saya memulai dari awal? Saya tidak yakin saya akan mampu melakukannya, tentu saja, tetapi setidaknya saya bersedia untuk melihatnya

menghapus banjir +1 dan komentar permintaan pembaruan status, silakan gunakan jempol untuk voting

EDIT: jika tidak ada pesan baru di feed ini, maka tidak ada yang baru untuk diceritakan

Jadi bagaimana hal ini dapat dilakukan sementara itu dalam satu permintaan tingkat atas (yaitu createTable ) tanpa harus menggunakan raw untuk seluruh pernyataan CREATE TABLE ? Atau haruskah kita createTable , lalu:

knex.raw('alter table `table` add fulltext (`col`)');

?

Ini sebenarnya tidak terlalu menyebalkan. Saya menyimpan semua skema saya dalam satu direktori, dengan nama file yang sesuai dengan nama tabel. Jadi untuk beberapa tabel foo yang tidak memerlukan pernyataan yang tidak didukung:

// foo.js

module.exports = function (table) {
  table.string(...);
};

dan untuk beberapa tabel bar yang membutuhkan indeks FULLTEXT :

// bar.js

module.exports = {
  builder: function (table) {
    table.string(...);
  },
  raw: function () {
    return knex.raw('alter table `bar` add fulltext (`col`)');
  }
};

Lalu saya hanya:

function createTable(table) {
  const schema = require('schemas/' + table);
  return (
    typeof schema === 'function'
      ? db.schema.createTable(table, schema)
      : db.schema.createTable(table, schema.builder)
        .then(() => schema.raw())
  ).catch(err => {
    logError(err.message);
  })
}

Masalah ini adalah yang teratas untuk banyak pencarian yang saya lakukan, tetapi tidak menjawab pertanyaan saya. Bagi mereka yang juga berakhir di sini karena alasan yang sama ...

Pengguna Postgres dapat menambahkan indeks teks lengkap ke kolom tsvector menggunakan argumen ketiga ke table.index . Sebagai contoh:

exports.up = (knex) => {
  return knex.schema.createTable('foo', (table) => {
    table.increments('id');
    table.specificType('fulltext', 'tsvector');

    table.index('fulltext', null, 'gin');
  );
);

Lihat juga:

https://knexjs.org/#Schema -index

dan

https://stackoverflow.com/questions/45871474/how-to-add-gin-index-using-knex-js

@rapodaca Terima kasih atas kontribusi Anda, menambahkan informasi ini ke wiki!

ini juga dapat menjadi solusi yang bermanfaat
http://blog.victorquinn.com/full-text-search-with-bookshelfjs

Apakah ini masih berhasil untuk kalian?
Saya telah mencoba menggunakan table.index ('title', null, 'FULLTEXT') dan hasil SQL adalah:
alter table `products` add index `products_title_index`(`title`)
Bahkan menggunakan table.index ('title', null, 'BOOM'), knex tidak membuat kesalahan dan hasil sql sama.

Apakah saya melewatkan sesuatu?

Menggunakan kueri RAW berfungsi.
ALTER TABLE products ADD FULLTEXT(title)

Guys) Saya telah memikirkan solusi tanpa. Lalu ():
table.index(null, 'product_fulltext_index', "GIN (to_tsvector('english', name || ' ' || description)); SELECT NOW");

Jadi knex guys sebaiknya menghapus () ketika fieldName nol dan kita bisa menyingkirkan SELECT NOW lampiran))

Komentar yang dihapus yang sama sekali tidak terkait (tentang penggunaan umum indeks sql).

Sudah cukup lama, ada pembaruan?

Tidak ada yang bahkan belum merancang dengan tepat bagaimana ini seharusnya bekerja dengan tepat. Melakukan pencarian teks lengkap dengan benar pada database tidak pernah semudah kedengarannya. Ini tidak akan semaju mesin FTS, tapi bisa berguna untuk beberapa kasus penggunaan ....

PR pasti akan sangat disambut.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat