Closed jimbung closed 9 months ago
Hi @jimbung ,
MiniSearch by default does not support searching in the middle of a word. It only supports searching at the beginning of the word, using prefix
search, and/or for slightly misspelled words using fuzzy
search.
That said, it is possible to implement search in the middle of the world, at the cost of a larger index, by following the instructions in this other discussion (and in particular in this comment).
Hi @lucaong , thank u very much for quick response on the issue. i tried as the following as the processTerm you mentioned above, but unfortunately some text cannot be searched out (before using processTerm function, they can be searched out). below is the code, please have a look if i am wrong with somewhere.
const suffixes = (term, minLength) => {
if (term == null) { return []; }
const tokens = [];
for (let i = 0; i <= term.length - minLength; i++) {
tokens.push(term.slice(i));
}
return tokens;
}
const idfield = "order_id";
const miniSearch = new MiniSearch({
idField: idfield,
fields: ["suscep", "action.comment", "action.game.comment"],
extractField: (document, fieldName) => {
const arrFields = fieldName.split(".");
if (arrFields.length === 2) {
return (document[arrFields[0]] || [])
.map((arrField: any) => arrField[arrFields[1]] || "")
.join(" ");
} else if (arrFields.length === 3) {
const tmparr = (document[arrFields[0]] || []).flatMap(
(arrField: any) => arrField[arrFields[1]] || []
);
return tmparr.map((s: any) => s[arrFields[2]] || "").join(" ");
}
// Access fields in simple path (such as a.b.c)
return fieldName
.split(".")
.reduce((doc, key) => doc && doc[key], document);
},
processTerm: (term) => suffixes(term, 3),
searchOptions: {
processTerm: MiniSearch.getDefault('processTerm'),
prefix: true,
},
});
Thanks!
Hi @jimbung ,
I did a quick test, only including the processTerm
logic and excluding the extractTerm
part, and it seems to work correctly:
const suffixes = (term, minLength) => {
if (term == null) { return []; }
const tokens = [];
for (let i = 0; i <= term.length - minLength; i++) {
tokens.push(term.slice(i));
}
return tokens;
}
const miniSearch = new MiniSearch({
fields: ["text"],
processTerm: (term) => suffixes(term, 3),
searchOptions: {
processTerm: MiniSearch.getDefault('processTerm'),
prefix: true,
},
});
const docs = [{id: 1, text: "something"}, {id: 2, text: 'something else'}]
miniSearch.addAll(docs)
miniSearch.search('thi')
/* >
[
{
id: 1,
score: 0.10047016592300792,
terms: [ 'thing' ],
match: { thing: [Array] }
},
{
id: 2,
score: 0.084675550210326,
terms: [ 'thing' ],
match: { thing: [Array] }
}
]
*/
Later today or tomorrow I will probably be able to test your code more in details. In the meanwhile, a few suggestions:
MiniSearch
version if you do not already use it.extractField
part or the processTerm
partGood luck!
Hi @lucaong , Thanks for quick reply. I am using "minisearch": "^6.2.0" currently. is it the latest? I'll check your suggestions later. Thank you very much!
Yes, its the latest 👍
@jimbung did you manage to resolve your problem? If not, you can post more details here, ideally some code to reproduce the problem, and I will try to help you.
hi @lucaong , thanks a lot for reminding me. Sorry i didnot post timely. The problem has been solved according to your suggestion. Thank u again for all the great helps :-)
Thank you @jimbung , happy to know your issue is solved! I will then mark the issue as closed.
Hi, When i search sth with the middle part of one word, is cannot return the items. for example, after create index for ''' { title: "this is a test" } ''' and i search "es", it returns null.
am I wrong with using it? thanks!