kbrsh / wade

:ocean: Blazing fast 1kb search library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Search object properties?

bajalovic opened this issue · comments

Is it possible to index objects by some properties, and then search by those fields?

For example

const search = Wade([{id: 1, name: "John Doe", email: "john@doe.com"}, {id: 2, name: "Another User", email: "another@user.com"}])

and then to search by query and property (that may be optional)

search("John", "name")
// or
search("com") // search all fields?

Or should I create different search instances for each property I want to search for?

It's not possible to do right now, but I could try adding it. It would increase the size to over 1kb though. I suppose I can accomplish this by holding an index and a property name in the trie, so I can increment the score for a property.

I would also have to add a new option to Wade, stating which properties should be searched over in case of properties not being strings (such as id in this case).

For now, I'd suggest making a new Wade instance for each property, maybe I can add some sort of plugin for this.

Why not to just add to_str?

It's harder because Wade generates and updates scores based on the array index, not object property names. @ctl

@kbrsh hi Kabir, good job on building a tiny search engine
Curious if you're planning to add that object reference so we could include ids.

Perhaps your lib was truly meant for minimalistic structure.

thanks

@jeveloper Thanks! I might, but not right now. Currently, I'm working on making the search index more memory efficient.

For now, you can try something like:

const documents = [
  {
    id: "foo",
    text: "bar"
  },
  {
    id: "bar",
    text: "baz"
  }
];

// Process into array of strings
let processed = [];
for(let i = 0; i < documents.length; i++) {
  const doc = documents[i];
  let str = "";

  for(let key in doc) {
    str += " " + doc[key];
  }

  processed.push(str);
}

const search = Wade(processed);

Thank you , that would be problematic , appreciate the tip

@kbrsh would it work to do something like this?
I mean it looks like it should work, but will the results still be good?

const objects = [
  {x: '1', y: '2', z: '3'},
  {x: '4', y: '5', z: '6'},
  ...etc...
];

const search = Wade(objects.map(obj => `${obj.x} ${obj.y} ${obj.z}` ));

search('2 3'); // Will it return the expected results?

@samuelgozi It depends on what you want. For example, with your search query 2 3, if you want the 2 to specifically search in the property x and the 3 to search in the property y, then it won't work. However, they will work if you want to search for text that can be in any object field. In your example above, Wade returns:

[
	{
		"index": 0,
		"score": 1.3333333333333333
	}
]

I want full text search for all of the fields combined, so it should work. Thanks for the clarification.

Edit: the question is, will it still be effective when the text gets very long?
In other words, does the algorithm just look for the occurrence of words, or does it take into account the distance between them?

It doesn't have anything special for the distance between words. Do you have an example of your use case for this? I think I can answer better if I have more information about your use case.