Reroute basic full text search to advanced value search with contain option

Hello, I am using Omeka S 4.2.0 and looking for a way to reroute the basic search to an advanced value search (property[0][joiner]=and&property[0][property]=&property[0][type]=in&property[0][text]=).

I don’t like the standard search behavior because you have to type in the full word to list the corresponding items. This is unintuitive for many users. So I want to change the behavior of the standard search to always use an advanced search.

I’ve looked into modules like Advanced Search but it seems to be a bit overkill for my use case. And it also seems to not change the public search bars. But I am not sure.

How would you approach this situation?

I highly encourage you to do the advanced search module. It is certainly a powerful, highly involved module to implement, but it also improves search dramatically on the admin side. It’s worth it for that alone.

I am not sure how to replace the public search forms with those of the “Advanced Search” module. Are there any tutorials for that?

My understanding is that, once in place, the search indexer powers ALL search bars, but I could be wrong. My evidence for this is that a search from the advanced search page with no parameters selected returns the same results in the same order as a simple search. That said, I’d ask @Daniel_KM to chime in here to see if that’s actually the case.

After activating the module, I still have the same search forms on the public site. My understanding is that I have to replace the public search forms in the theme to use the page configured in the Search manager of the Advanced Search module. Is this the right approach? Or is there a simpler more robust way?

Hi, the problem comes from the way the fulltext search is run against the fulltext_search table in the database. My uderstanding is that this table is updated each time a ressource is added, updated or deleted. In this table, the field “text” holds a concatenation of the values of the text properties of the resource.

Looking at the code of the file /omeka-s/application/Module.php, you find the following:

public function searchFulltext(ZendEvent $event)
{

    ...

    $match = 'MATCH(omeka_fulltext_search.title, omeka_fulltext_search.text) AGAINST (:omeka_fulltext_search)';

    ...

This means that the fulltext search is done by using MySQL MATCH() and AGAINST() functions in the query.

Let’s say you are looking for the word “rabbit”. The resulting query will look a bit like this:

SELECT * FROM fulltext_search WHERE MATCH(title, text) AGAINST('rabbit')

which will return only the resources that contain the exact word “rabbit” but not the ones that contain “rabbits” for example.

The solution to your problem would be to modify the query like this:

SELECT * FROM fulltext_search WHERE MATCH(title, text) AGAINST('*rabbit*' IN BOOLEAN MODE)

A “functional hack” can be to modify the Module.php like this:

public function searchFulltext(ZendEvent $event)
{

    ...

    // $match = 'MATCH(omeka_fulltext_search.title, omeka_fulltext_search.text) AGAINST (:omeka_fulltext_search)';
    $query['fulltext_search'] = sprintf('*%s*', $query['fulltext_search']);
    $match = 'MATCH(omeka_fulltext_search.title, omeka_fulltext_search.text) AGAINST (:omeka_fulltext_search IN BOOLEAN MODE)';

    ...

Of course, remember this is a hack :wink:

1 Like

Right, it’s the fulltext search going on here, which defaults to matching full words only. We may think about just making the default in boolean mode here in the future, though you’d still have to put the asterisk truncation operator in. (Note: if I’m recalling correctly, the asterisk only has an effect at the end of a search term: in other words, even in boolean mode, you can’t use them on both sides to match some substring in the middle of a word like you might with the “contains” search.)

If you want to just do a contains search from the basic search form, you might consider just replacing the search form in your theme.

<form method="get" action="<?php echo $this->url('site/resource', ['controller' => 'item', 'action' => 'browse'], true); ?>">
    <input type="text" name="property[0][text]">
    <input type="hidden" name="property[0][property]" value="">
    <input type="hidden" name="property[0][type]" value="in">
    <button id="search-submit" type="submit" aria-label="<?php echo $translate('Submit'); ?>" title="<?php echo $translate('Submit'); ?>"><span class="o-icon-search" aria-hidden="true"></span></button>
</form>

You could override the common/search-form.phtml partial to most easily alter the search form.

1 Like

Thank you for your time. I think the boolean mode approach is more flexible and faster for larger collections. But in my case people just want to type some part of a word and want to list all the objects that can be found with it.

I don’t really see the value in the basic search without boolean mode, if I am honest.

I will test the changes and report back, if everything works.

I’ve changed the common/search-form.phtml partial inside my theme with your provided code and it worked perfectly. Thank you again. This is the solution for my problem. :+1:

Now the only problem that is not resolved is the cross-site search form. I am not sure if an advanced search is as easily usable in this case.