how to do prefix and suffix search on full text indexed table - sql-server

How to query a full text table like "like" operator? Suffix search is not fetching the result... i am using contains and searching in all the columns.Can you please help , how to do suffix search on full text indexed table

You can perform a prefix search using the wildcard operator:
SELECT Description, ProductDescriptionID
FROM Production.ProductDescription
WHERE CONTAINS (Description, ' "top*" ' );
(Source)
Suffix searches are not supported. You have to do a hack like keep a copy of the reversed text as shown here.

Related

Match all documents excluding some terms using full Lucene syntax

Our service's default search web page uses the * full Lucene query to match all documents. This is before the user has provided any search terms. There is some data (test data, in our case) that we want to exclude from the search result.
Is it possible to match all documents but exclude a subset of all documents?
For example, suppose we have an "owners" field and we want to exclude documents with the "testA" and "testB" owner. The following query does not seem to work with the match all approach:
Query: search=* -owners:testA -owners:testB&queryType=full&$orderby=created desc
Error: "Failed to parse query string. See https://aka.ms/azure-search-full-query for supported syntax."
When searching for anything but *, this approach works fine. For example:
Query: search=foo -owners:testA -owners:testB&queryType=full&$orderby=created desc
Result: (many documents matched)
I have considered a $filter for this and using $filter=filterableOwners/all(p: p ne 'testa' and p ne 'testb') but this has the following drawbacks:
the index must be rebuild with a filterable field
analyzers can't be used so case-insensitivity must be implemented by lowercasing the values and filter expression
Ideally this could be done using only the search query parameter with a Lucene query text.
I found a workaround for the issue. If you have a field in your documents that always has a value, you can use a .* regex to match all values in the field and therefore match all documents.
For example, suppose the packageId field has a value for all documents.
Incorrect (as posted in the original question):
Query: search=* -owners:testA -owners:testB&queryType=full&$orderby=created desc
Correct:
Query: search=packageId:/.*/ -owners:testA -owners:testB&queryType=full&$orderby=created desc

SQL Contains() with a single word does not return all expected rows

I am running a simple SQL contains search and the result does not include all expected rows.
All I need is a search that works in the same way as LIKE %word%.
SELECT *
FROM [MyTable] where contains(Name, N'walmart')
By running this select, the rows returned seem to only contains name with "walmart" with either space before or after or some kind of other delimiter like a period ("walmart.com"). No problem here.
But one row was not returned and its value is "mywalmart". Why does this row fail to return with the contains search? If I use name LIKE '%walmart%' it works just fine.
What do I need to fix the contains search to make it work?
Contains doesn't work the way you think, for your purposes LIKE is best.
See the docs on this:
CONTAINS can search for:
A word or phrase.
The prefix of a word or phrase.
A word near another word.
A word inflectionally generated from another (for example, the word drive is the inflectional stem of drives, drove, driving, and driven).
A word that is a synonym of another word using a thesaurus (for example, the word "metal" can have synonyms such as "aluminum" and "steel").

Matching words in close proximity

I have a table in SQL 2012 that I'm performing a full text search on.
One of the records has, as a part of a larger string, the text 'Trying out your system'.
The problem is that, if I search for two words in the target string which are too close together, I don't get a match.
select * from mytable where contains(*,'trying') -- match
select * from mytable where contains(*,'trying and out') -- no match
select * from mytable where contains(*,'trying and your') -- no match
select * from mytable where contains(*,'trying and system') -- match
I'm aware that I can search for an exact string by enclosing the search pattern in double quotes, however that's not really what I'm after.
Any suggestions how I can make all of the above search terms match?
Thanks.
This sounds like an issue with stopwords (common words like "the", "your", etc. that are usually filtered out of the full text index, thus you cannot search on them).
To prevent this from happening, you can modify your full text index so that it does not use a stoplist (in other words, every single word will be indexed and thus searchable).
ALTER FULLTEXT INDEX ON MyTable SET STOPLIST = OFF
Be sure to rebuild the full text catalog afterwards.
But only do this if you really need the ability to search on common words. Typically this is not necessary. Also, doing so may slow down your full text searches.

Search API, how to like query

I'm using the Search API GAE, how to make a query like "like%"? as is done in SQL example:
select * from person where name like '% john%';
your queryString would be "name: john" on the person index with name field set to be a Text field.
A regular query with ':' or '=' on the Text or HTML type of index value is closest (not same) to 'like' in SQL.
Details on available operators to use in the query are at
https://developers.google.com/appengine/docs/java/search/query_strings#Java_Queries_on_text_and_HTML_fields.
Also check stemming if your use-case is to find words with similar meaning.
https://developers.google.com/appengine/docs/java/search/query_strings#Java_Stemming

SQL Server Full Text Search Leading Wildcard

After taking a look at this SO question and doing my own research, it appears that you cannot have a leading wildcard while using full text search.
So in the most simple example, if I have a Table with 1 column like below:
TABLE1
coin
coinage
undercoin
select COLUMN1 from TABLE1 where COLUMN1 LIKE '%coin%'
Would get me the results I want.
How can I get the exact same results with FULL TEXT SEARCH enabled on the column?
The following two queries return the exact same data, which is not exactly what I want.
SELECT COLUMN1 FROM TABLE1 WHERE CONTAINS(COLUMN1, '"coin*"')
SELECT COLUMN1 FROM TABLE1 WHERE CONTAINS(COLUMN1, '"*coin*"')
Full text search works on finding words or stems of words. Thus, it does not find the word "coin" anywhere in "undercoin". What you seek is the ability search suffixes using full text searches and it does not do this natively. There are some hacky workarounds like creating a reverse index and searching on "nioc".

Resources