Search "Our" Use Full Text Search with Contains in SQL Server - sql

We Use Full text search and Contains to search between records in SQL Server 2008 R2, here are the samples:
NEWS(Title): "We", "New", "Our", "Long-Term", "Seem", "Non.Active"
So as you see in the News table the title field have the values.
We can search all of the values except "Long-Term" And "Non.Active", actually we can not search the words includes dash("-") or dot("."). We also check these tips:
SELECT * FROM NEWS WHERE Contains(Title, 'Non.Active');
SELECT * FROM NEWS WHERE Contains(Title, 'Non Active');
SELECT * FROM NEWS WHERE Contains(Title, 'NonActive');
SELECT * FROM NEWS WHERE Contains(Title, 'Non*');
SELECT * FROM NEWS WHERE Contains(Title, 'Active');
SELECT * FROM NEWS WHERE Contains(Title, 'Non');
SELECT * FROM NEWS WHERE Contains(Title, '*Active');
SELECT * FROM NEWS WHERE Contains(Title, ' "Non.Active" ');
SELECT * FROM NEWS WHERE Contains(Title, ' "Non Active" ');
SELECT * FROM NEWS WHERE Contains(Title, ' "NonActive" ');
SELECT * FROM NEWS WHERE Contains(Title, ' "Non*" ');
SELECT * FROM NEWS WHERE Contains(Title, ' "*Active" ');
SELECT * FROM NEWS WHERE Contains(Title, ' "Active" ');
SELECT * FROM NEWS WHERE Contains(Title, ' "Non" ');
But none of them return any result.
Also we rebuild Full Text Index and yet we did not get any result.
So the question is: Is there any way to search the words include "." or "-" with full text Contains predicate? any suggestion
UPDATE
I'm really sorry the main problem is another?
you all right about two words of "non" and "Action". but the main case I test it is "We.Our" and steel not return any result? That's so wired, I test "Non.Action" with above search and worked but "We.Our" don't. So I try another record, I inserted the "our" and the search result is yet null. The problem is about "Our" word? what is the problem with "our" I also check it in SQL Server 2012, and not worked also. is there any one have any idea about this?

You can check how needed data is stored in Fulltext catalog:
SELECT *
FROM sys.dm_fts_index_keywords_by_document(db_id('DBname'), object_id('TableName'))
WHERE document_id = <Unique Id>
What about the "our" word, it seems to be a stop-word.

The point is the Block words and Noisy words should be checked, in my case the our was a noisy word, I don't know why. but the problem solved

In My cases, it simply works as
SELECT * FROM NEWS WHERE Contains(Title,'"Non.*"');
But i hear there is little bug in 2008 version.May the problem will solve after updating sql server instances.

Related

Multi keywords search with SQL

I'm using a search bar on my website based on keyup binding and ajax requests. It works fine but I would like my search engine to be able to have finner result with multi keywords management.
However I could not find any simple method to set up this kind of search method.
Does anyone knows how to set this up ?
Here is the actual SQL request that's being made:
if ($recherche !=""){
$req = $this->bdd->prepare("SELECT * FROM videos WHERE titre LIKE :recherche OR auteur LIKE :recherche UNION SELECT videos.id_video, videos.titre, videos.lien, videos.auteur, videos.date_upload FROM videos RIGHT JOIN mots_clefs ON videos.id_video = mots_clefs.id_video AND mots_clefs.mot_clef LIKE :recherche ORDER BY date_upload DESC LIMIT ".$start.", ".$limit);
$req->execute(array('recherche' => "%".$recherche."%"));
$result = json_encode($req->fetchAll(PDO::FETCH_ASSOC));
}
Request example:
SELECT * FROM videos WHERE titre LIKE '%word 1 word 2%' OR auteur LIKE '%word 1 word 2%' UNION SELECT videos.id_video, videos.titre, videos.lien, videos.auteur, videos.date_upload FROM videos RIGHT JOIN mots_clefs ON videos.id_video = mots_clefs.id_video AND mots_clefs.mot_clef LIKE '%word 1 word 2%' ORDER BY date_upload DESC LIMIT 0, 20);
You can execute the above query in a loop by passing one keyword at a time.
get the entire keyword list provided by the user into a sting.
Use string.Split() method by passing comma(,) as delimiter to get the list of the keywords into an array list.
loop through the array list and pass to the query.
Make sure you append the data fetched from the SQL into a data table or dataset and Not rewrite it.
string select = "SELECT * FROM [MyTable] WHERE [Title] LIKE '%" + strSearch.Replace(",", "%' OR [Title] LIKE '%") + "%'";

Query Rewrite Template in Oracle SQL

I have a Oracle SQL Query as below :
select id from docs where CONTAINS (text,
'<query>
<textquery lang="ENGLISH" grammar="CONTEXT"> Informix
<progression>
<seq><rewrite>transform((TOKENS, "{", "}", "AND"))</rewrite></seq>
</progression>
</textquery>
</query>')>0;
The Query Works as expected. But I want to search for word Inform / Infor / Info. So I altered the query to below :
select id from docs where CONTAINS (text,
'<query>
<textquery lang="ENGLISH" grammar="CONTEXT"> Informix
<progression>
<seq><rewrite>transform((TOKENS, "?{", "}", "AND"))</rewrite></seq>
</progression>
</textquery>
</query>')>0;
By adding extra "?" in transform function. But this looks for informix / informi / inform / infor / info / inf / in. I want to restrict the search to a specific characters 4. Say till info. How can the same be achieved?
Thanks.
To find all documents that contain at least one occurrence of any of the terms between informix and info use the OR operator
and list all you allowerd terms in the template
<query>
<textquery lang="ENGLISH" grammar="CONTEXT"> informix informi inform infor info
<progression>
<seq><rewrite>transform((TOKENS, "{", "}", "OR"))</rewrite></seq>
</progression>
</textquery>
</query>
But the usage of template is not realy meaninfull here.
The same result you get with a direct query
select score(1), id from docs
where contains(text,'informix OR informi OR inform OR infor OR info',1) > 0
order by 1 desc;
The advantage of this case is that you can controll the score by prefering the documents with longer string with higher weights
select score(1), id from docs
where contains(text,'informix*5 OR informi*4 OR inform*3 OR infor*2 OR info',1) > 0
order by 1 desc;
Btw the ? (fuzzy) operator is used IMO to find misspelled words, not the exact prefixes of a term.
UPDATE
The concatenation of the prefixes you may assembly in PL/SQL or if necessary in SQL such as follows:
with txt as (
select 'informix' text from dual),
txt2 as (
select
substr(text,1,length(text) -rownum+1) text
from txt connect by level <= length(text) -3
)
select
LISTAGG( text, ', ') WITHIN GROUP (ORDER BY text desc)
from txt2
.
informix, informi, inform, infor, info

SQL Server can not find word

When I search for the Dünyas word with a LIKE operator I can see the results but when I search Dünyası word with LIKE operator, it returns no results. Problem is not ı or ü letters I tried with i and u letters as well.
This query:
select * from DbDivx where NameTurkish like '%Dünyas%' =>
returns:
Boksörün Dünyası
Geleceğin Dünyası
Su Dünyası
However:
select * from DbDivx where NameTurkish like '%Dünyası%' =>
returns nothing.
Can you help me please?
http://sqlfiddle.com/#!6/8c359/1
create table test (someName nvarchar(300))
insert into test (someName)
select N'Boksörün Dünyası'
union all select N'Geleceğin Dünyası'
union all select N'Su Dünyası'
select * from test where someName like N'%Dünyası%'
Not having any issues with the above fiddle. Note that when i inserted data without the N in front of it, the like query did not return results.
hopefully this helps!

echo out from the UNION sql?

<?php
$sql = mysql_query("
SELECT navn FROM member_film WHERE username = '$pusername'
UNION SELECT meetup FROM member_meetups WHERE byusername = '$pusername'
UNION SELECT title FROM member_tutorials WHERE username = '$pusername'");
$rowit = mysql_fetch_array($sql);
$number = mysql_num_rows($sql);
?>
<? echo $number; ?>
<? echo $rowit["navn"]; ?><br>
<? echo $rowit["meetup"]; ?><br>
So i have this.
Now, i have 3 columns where username is username in the database.
2 in member_film, 1 in member_meetups
The echo $number, shows it correct, that i have 3.
Now when i try to echo the "navn", it echo only 1, when there is 2 columns?
And when i try to echo "meetup" it says undefined index: meetup, like there's nothing to show..
but there is, mysql_num_rows founded it, else it would have been 2?
I think most of you misunderstood me..
I want to show what the user($pusername) have been posted, in member_film, member_meetups, member_tutorials.. And then if e.g the user have 2 columns with his username, i want to display the "navn" from the same column. Same with title on member_tutorials, and meetup on member_meetups.
An example on how i want it to look like:
Your posts: (which as i want, checks the three table if there's any columns with the user's username in "username" column.)
My new video, its so good (navn, which is from member_film)
My boring meetup with my parents (title, which is from member_meetup)
My great great video!(navn, which is from member_film)
UNION selects, are joining select statements into 1 result set, therefor have the same column names.
Correct SQL:
SELECT navn colName, 'member_film' tableName FROM member_film WHERE username = '$pusername'
UNION SELECT meetup colName, 'member_meetups' tableName FROM member_meetups WHERE byusername = '$pusername'
UNION SELECT title colName, 'member_tutorials' tableName FROM member_tutorials WHERE username = '$pusername'");
and in the php:
<? echo $rowit["colName"]; ?><br>
and to find out what table:
<? echo $rowit["tableName "]; ?><br>
A union query combines the results of several queries into one resultset. In order for the union to work all subqueries have to return the fields with the same data types for each position of the query or each named field.
So your original query will result in a result set with one field called "navn" (taken from the first sub query of the union). So to make it more readable you could either rename the field using As myName on each of the subqueries (sam munkes' solution).
However, from the way you are accessing the query I believe you want to have one row with all 3 values on it then you should try using this instead:
SELECT member_film, member_meetups.meetup, meber_tutorials.title
FROM member_film, member_meetups, member_tutorials
WHERE member_film.username = '$pusername' AND
member_film.username = member_meetups.byusername AND
member_film.username = member_tutorials.username
Edit after the comments:
SELECT CONVERT(varchar(100), navn) AS Comment FROM member_film WHERE username = '$pusername'
UNION
SELECT CONVERT(varchar(100), meetup) AS Comment FROM member_meetups WHERE byusername = '$pusername'
UNION
SELECT CONVERT(varchar(100), title) AS Comment FROM member_tutorials WHERE username = '$pusername'
This should now yield a table having one column named 'comment' and being of varchar(100). You can now access all values via the comment column. If you need to know from which table the information is taken, use Sam's answer. I inserted the convert to ensure that all entries are of the same data type and length, if they are in you DB you can leave this portion out and just use the names. If needed the length needs to be adjusted.
To make it clear, there is only one column with the name "comment" now.

SQL Server 2008 full-text search doesn't find word in words?

In the database I have a field with a .mht file. I want to use FTS to search in this document. I got this working, but I'm not satisfied with the result. For example (sorry it's in dutch, but I think you get my point) I will use 2 words: zieken and ziekenhuis. As you can see, the phrase 'zieken' is in the word 'ziekenhuis'.
When I search on 'ziekenhuis' I get about 20 results. When I search on 'zieken' I get 7 results. How is this possible? I mean, why doesn't the FTS resturn the minimal results which I get from 'ziekenhuis'?
Here's the query I use:
SELECT DISTINCT
d.DocID 'Id',
d.Titel,
(SELECT afbeeldinglokatie FROM tbl_Afbeelding WHERE soort = 'beleid') as Pic,
'belDoc' as DocType
FROM docs d
JOIN kpl_Document_Lokatie dl ON d.DocID = dl.DocID
JOIN HandboekLokaties hb ON dl.LokatieID = hb.LokatieID
WHERE hb.InstellingID = #instellingId
AND (
FREETEXT(d.Doel, #searchstring)
OR FREETEXT(d.Toepassingsgebied, #searchstring)
OR FREETEXT(d.HtmlDocument, #searchstring)
OR FREETEXT (d.extraTabblad, #searchstring)
)
AND d.StatusID NOT IN( 1, 5)
I would suggest that you look at using the CONTAINS predicate, as opposed to FREETEXT
Usage scenarios, including what you wish to achieve, can be found in the examples section of the documentation.
From your description, I believe that you are attempting to perform a "Prefix" search. For example:
USE AdventureWorks;
GO
SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' "SearchTerm*" ');
GO
This will provide you a result set containing all words that "contain" the prefix search term.