Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A frustrating experience #120

Closed
XGhozt opened this issue Dec 2, 2017 · 12 comments
Closed

A frustrating experience #120

XGhozt opened this issue Dec 2, 2017 · 12 comments

Comments

@XGhozt
Copy link
Contributor

XGhozt commented Dec 2, 2017

As great as this library boasts to be, and as much as I wanted to use it, I just couldn't. For whatever reason, searching partial keywords does not return the expected results. On top of that, there's no easy way to return more then just the ID in the results. After a few hours, I've abandoned this.

If anyone has any solutions for the above I would be curious though.

@ultrono
Copy link

ultrono commented Dec 4, 2017

@XGhozt00 I assume you're using the packagae standalone. Searching is very clearly explained in the documentation - see https://github.com/teamtnt/tntsearch#searching :)

I quote from the documentation:

//to display the results you need an additional query
//SELECT * FROM articles WHERE id IN $res ORDER BY FIELD(id, $res);

@nticaric nticaric closed this as completed Dec 5, 2017
@XGhozt
Copy link
Contributor Author

XGhozt commented Dec 5, 2017

Thanks @ultrono -- that part of the documentation did not make any sense to me. Where does that query go? I used larger query when generating the index and it still returned only the ID. The search methods use a string/keywords to search, so.. where does this query go?

This also doesn't solve the issue when searching for partial words. If I search for "rom", "romeo" should be returned in the results, but that wasn't happening for me. I saw other issues when searching for a solution from people with the same problem.

@stokic
Copy link
Contributor

stokic commented Dec 5, 2017

You should read the documentation again, it says explicitly that it will return only ids:

$res = $tnt->search("This is a test search", 12);

print_r($res); //returns an array of 12 document ids that best match your query

//to display the results you need an additional query
//SELECT * FROM articles WHERE id IN $res ORDER BY FIELD(id, $res);

The steps are pretty clear, just repeat them exactly as show in the documentation and that's it.

@XGhozt
Copy link
Contributor Author

XGhozt commented Dec 5, 2017

Thanks @stokic -- "exactly as documentation" isn't clear enough. The docs are just showing a commented out query string. Does this query get run against the sqlite database or the actual application database, thus not using the cache? This could potentially require hundreds of additional queries depending on how the results are shown, wouldn't that defeat the purpose? I could create a method to do this for me automatically when a search is made, but I couldn't figure out how to use tntsearch to actually execute the query. Is this not possible? Do I just use the pdo driver to query the index again without using tntsearch?

I really appreciate all the assistance/feedback here. Would you be able to provide an example of how one might actually execute that additional query using tntsearch?

@stokic
Copy link
Contributor

stokic commented Dec 5, 2017 via email

@XGhozt
Copy link
Contributor Author

XGhozt commented Dec 5, 2017

Got it, thanks so much.

@XGhozt
Copy link
Contributor Author

XGhozt commented Dec 5, 2017

I guess the partial word issue is just that, an issue.
This project is nice I imagine it's easier to use with something like Laravel.

@nticaric
Copy link
Contributor

nticaric commented Dec 5, 2017

Let me try to do a high-level explanation of full text search. Usually, you will have a data source containing some documents. Each document will have an unique id. In praxis, the datasource is an mysql database ie. and the documents are rows in a table.
What full text search does is, it creates an index which stores all of the words from those documents together with the document id. This is called an inverted index.
Now, that you have this inverted index, you make queries against it, searching for a word and the inverted index will return the document id where this word can be found. So if you want to display
this document to the user, you have to query your data source. Your question might be why not query the datasource directly, right? Well, it has some performance issues and you can read more about here http://tnt.studio/blog/solving-the-search-problem-with-laravel-and-tntsearch

@XGhozt
Copy link
Contributor Author

XGhozt commented Dec 5, 2017

Fantastic, thanks so much! @nticaric

@ultrono
Copy link

ultrono commented Dec 6, 2017

@XGhozt00 to add onto the above, if you used the TNT Search Laravel Scout driver everything is abstracted away for you. So you can keep things very simple and use the following API:

$orders = App\User::search('Rob')->get();

Behind the scenes Laravel is searching upon (in this case), order ids returned from the index, against you application database.

The framework agnostic version of TNT Search (i.e. this repo) returns a list of ordered document ids. You've probably saw the sample query from the documentation:

//SELECT * FROM articles WHERE id IN $res ORDER BY FIELD(id, $res);

The $res variable is a list of comma separated primary key from your database. So in the above orders example you ultimate query would be along the line of:

$res = $tnt->search("Rob", 12);
$ids = implode (",", $res);
SELECT * FROM users WHERE id IN ($ids) ORDER BY FIELD(id, $ids);
// i.e. SELECT * FROM users WHERE id IN (10, 50) ORDER BY FIELD(id, 10, 50); 

@XGhozt
Copy link
Contributor Author

XGhozt commented Dec 6, 2017

Thanks @ultrono that's great! I've several active projects in Laravel, the one I was using this for was about 6 years old and unfortunately, not Laravel. I will give this a shot again in the future though.

@sebastienbarre
Copy link

@XGhozt is not completely wrong :)

$indexer = $tnt->createIndex('name.index');
$indexer->query('SELECT id, article FROM articles;');

This seems to imply you can only index one table, the articles table.

There are 90+ tables in our app, with at least 20 tables that each contains documents with multiple fields that could be indexed and searched against. For example, picture a contracts table, with a description and special_terms fields, both to be indexed. In the same database, there would also be a projects table, with its own name, description, keywords fields to index, etc. Each table has its one primary id key.

It is not clear from the documentation if that can be done. I assume it can be done, since indexing only one table would only satisfy the needs of small applications.

The call to $tnt->search() returns an array of ids, which seems to confirm that multiple tables are not supported for that specific API. Maybe it's possible, but not at first glance.

  • Should $tnt->createIndex() be called for each table one wants to index?
  • Can $tnt->selectIndex() be called on multiple indexes -- in other words, can you search on multiple tables at the same time? Probably not, since it returns an array of ids, not an array of (table, id) pairs.
  • If the above is not possible, does it mean you have to call $tnt->search() for each separate table, and merge all the results? Meaning, you have to maintain indexes for all tables manually? Is that efficient?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants