lucaong / minisearch

Tiny and powerful JavaScript full-text search engine for browser and Node
https://lucaong.github.io/minisearch/
MIT License
4.9k stars 137 forks source link

miniSearch.toJSON() + miniSearch.loadJSON() combination doesn't work #10

Closed kal4evskiy closed 5 years ago

kal4evskiy commented 5 years ago

miniSearch.toJSON() + miniSearch.loadJSON() combination doesn't work because of absence options in the toJSON() output as a result - error regarding absence of options.fields property

second issue is that with miniSearch.loadJSON(jsonObj) jsonObj have to be JSON.stringified string and miniSearch.toJSON() provides non-stringified one instead

lucaong commented 5 years ago

Hi @kal4evskiy , thanks for reporting the issue.

Admittedly, the JSON serialization/deserialization of the index is the only feature still in "beta" state (the documentation mentions it, but I should make it clearer). The main issues with it are:

  1. As you correctly noted, options are not serialized (some of them, e.g. functions, are not serializable), and must be provided to loadJSON with the same value that was originally used

  2. The serialization format is very dependent to the index implementation

In practice, re-indexing is often fast enough (and even faster in some mobile browsers due to slow JSON parsing), so this feature was left in a "beta" state until enough use-cases are collected.

I am currently leaning toward re-implementing JSON serialization almost entirely, using a format that would be slightly slower to load, but more implementation agnostic, and simpler to store and compress. Even then, it won't be possible to serialize options, so they should be provided upon JSON loading. I will improve it by raising an error if options are not supplied though, because I agree that the current behavior is confusing.

Until then, you can pass options to loadJSON a the second argument, making sure to use the same values as when the index was serialized.

lucaong commented 5 years ago

As for the behavior of toJSON, it is mandated by the [JavaScript standard](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior): an object can implements a toJSON method, returning a serializable object, that will be used by JSON.stringify.

Therefore, to produce the serialized index, you can use JSON.stringify(miniSearch)

lucaong commented 5 years ago

I just released v2.0.1 that raises a more descriptive error when calling loadJSON without passing options. I hope this will help users that may run into the same problem, so I am closing this issue.

More improvements to the serialization logic will come in a future release, but full serialization of options will probably not be practical.

Thanks again for reporting!