nextapps-de / flexsearch

Next-Generation full text search library for Browser and Node.js
Apache License 2.0
12.53k stars 491 forks source link

Import/export broken in 0.7.21? #290

Closed alangibson closed 2 years ago

alangibson commented 3 years ago

I can't seem to get index export/import working in 0.7.21. If I export an index and immediately import it, then I never get any search results. I'm not sure if I'm reading the docs wrong, or if this really is a bug.

The following test fails:

`import { assert } from 'chai'; import { Index, IndexSearchResult } from 'flexsearch';

describe('flexsearch', () => {

it('should search after export and import', async () => {

    // Given
    const exportIndex = new Index();
    const importIndex = new Index();
    await exportIndex.addAsync('one', 'stuff and junk');
    await exportIndex.addAsync('two', 'derp derp');

    // When
    await exportIndex.export(async (key, value) => {
        await importIndex.import(key, value);
    });
    const r: IndexSearchResult = await importIndex.searchAsync('junk');

    // Then
    assert.equal(r.length, 1);
});

});`

alangibson commented 3 years ago

I think I figured it out. There were actually 3 problems. This test now passes:

` it('should search after export and import', async () => {

    // Given
    const exportIndex = new Index();
    const importIndex = new Index();
    await exportIndex.addAsync('one', 'stuff and junk');
    await exportIndex.addAsync('two', 'derp derp');

    // When

    // We need to fix the key names, so store them here
    const d: { [key: string]: string } = {};
    // Contrary to the docs, neither export() nor import() are actually 
    // declared async
    exportIndex.export((key: string|number, value) => {
        // Keys don't match between import() and export()
        // export() nests keys like reg, reg.cfg, reg.cfg.map, and reg.cfg.map.ctx
        // but import() wants them flat like reg, cfg, map, ctx
        const k = key.toString().split('.').pop() || '';
        d[k] = value;
        importIndex.import(k, value);
    });

    // We have to sleep because of function async() in serialize.js
    // It looks like some homemade async. There is a comment stating
    // "await isn't supported by ES5"
    await new Promise(resolve => setTimeout(resolve, 3000));

    const r: IndexSearchResult = await importIndex.searchAsync('junk');

    // Then
    assert.equal(r.length, 1);
});`
Properko commented 3 years ago

I'm having the same problem with export asynchronicity. I check for exporting store.json before resolving the promise, which seems to always be the last key to go, but it's pretty ugly to rely on the internals like this. I find it preferable to timeouts though.

const exportAsync = (docIndex, filePath) =>
  new Promise((resolve, reject) => {
    try {
      return docIndex.export(async (key, data) => {
        try {
          await fsPromises.mkdir(filePath, { recursive: true });
          const filename = `${filePath}/${key}.json`;
          await fsPromises.writeFile(filename, data !== undefined ? data : '');
          if (key === 'store') {
            resolve(); // store is the last to go, but this relies on internals and assumes no error occurs in the process :(
          }
        } catch (err) {
          reject(err);
        }
      });
    } catch (err) {
      reject(err);
    }
  });
o0101 commented 2 years ago

@alangibson thanks! This worked for me, too. Un-nesting the keys and using the last step in the key path, works a treat. Thank you! 😛 😉 xx 😜

    exportIndex.export((key: string|number, value) => {
        // Keys don't match between import() and export()
        // export() nests keys like reg, reg.cfg, reg.cfg.map, and reg.cfg.map.ctx
        // but import() wants them flat like reg, cfg, map, ctx
        const k = key.toString().split('.').pop() || '';
        d[k] = value;
        importIndex.import(k, value);
    });

✔️ SOLVED

ts-thomas commented 2 years ago

This is now fixed in v0.7.23 Further improvements to provide Promise.all() compatible export ist coming in next version.