Once I was working with a custom search webpart issue in which search was implemented by using FullTextSqlQuery method, but it was not returning any results whenever we use contains predicate to filter the date time type columns.

There was a custom managed property of type Date Time to filter in the custom webpart. Since it was not returning any results in the custom webpart, we added that managed property in OOB advance search web part to include the custom managed property in the pick property section. After that, selected the date time managed property and executed the search by giving the same value that we given in the custom search webpart and it returned the correct results. We also checked the ULS logs to check the query used to execute the search with the date time type managed property in the filtering condition.

We saw that there is a difference in the construction of query between the custom webpart and the query executed in OOB (out-of-the-box).

SharePoint has only 3 filtering conditions with any managed property of type Date and Time. So, we must need to construct a query in a way that SharePoint can internally understand. If you pass ‘07/08/2009’ as your input date value SharePoint will convert that input date value in the format of ‘2009/07/08 18:30:00’ internally. You can see the query in the ULS logs once you execute a search in UI.

I have captured the SQL syntaxes for all the three filtering conditions. (eg: 07/08/2009 as our input date value)


Equal

Full Text Query: SELECT WorkId, Rank, Title, Author, Size, Path, Description, Write, SiteName, CollapsingStatus, HitHighlightedSummary, HitHighlightedProperties, ContentClass, IsDocument, PictureThumbnailURL  from scope() where ("scope" = 'All Sites') And ((Created >= '2009/07/07 18:30:00' and Created < '2009/07/08 18:30:00'))


Earlier than

Full Text Query: SELECT WorkId, Rank, Title, Author, Size, Path, Description, Write, SiteName, CollapsingStatus, HitHighlightedSummary, HitHighlightedProperties, ContentClass, IsDocument, PictureThumbnailURL  from scope() where ("scope" = 'All Sites') And (Created < '2009/07/08 18:30:00')


Later than

Full Text Query: SELECT WorkId, Rank, Title, Author, Size, Path, Description, Write, SiteName, CollapsingStatus, HitHighlightedSummary, HitHighlightedProperties, ContentClass, IsDocument, PictureThumbnailURL  from scope() where ("scope" = 'All Sites') And (Created > '2009/07/08 18:30:00')

You can refer the above syntaxes for building your SQL query for filtering date type managed properties.

아래는 FullTextSqlQuery를 이용하고,
검색 범위를 지정하여 해당 범위안에 있는 아이템을 검색하는 소스이다.


string strQuery = string.Empty;
string strkeyword = "Microsoft";

ServerContext context = ServerContext.Current;
FullTextSqlQuery kQuery = new FullTextSqlQuery(context);

strQuery = "SELECT Title, HitHighlightedSummary, Write, ContentClass, Department, IsDocument, Path, Author, Size, SiteTItle FROM Scope() WHERE \"scope\" = 'Search' AND FREETEXT(defaultproperties, '" + strkeyword + "')";
    //Search는 중앙 관리에서 생성한 검색 범위명
    
kQuery.QueryText = strQuery;
kQuery.ResultTypes = ResultType.RelevantResults;
kQuery.StartRow = 0;
kQuery.RowLimit = 50;
kQuery.EnableStemming = true;
kQuery.TrimDuplicates = true;
kQuery.HighlightedSentenceCount = 3;
kQuery.Culture = CultureInfo.CurrentCulture;
kQuery.KeywordInclusion = KeywordInclusion.AllKeywords;
kQuery.Timeout = 60000;
kQuery.AuthenticationType = QueryAuthenticationType.NtAuthenticatedQuery;

ResultTableCollection resultTbls = kQuery.Execute();
if ((int)ResultType.RelevantResults != 0)
{
       ResultTable tblResult = resultTbls[ResultType.RelevantResults];

       DataTable resultDataTable = new DataTable();
       resultDataTable.Load(tblResult, LoadOption.OverwriteChanges);

       gvSearchResult.DataSource = resultDataTable;
       gvSearchResult.DataBind();
}

특정 문서 라이브러리에 대한 리스트 아이템에 대해서 검색하도록 검색 범위를 지정한 후,
해당 문서 라이브러리에 여러 문서를 업로드한다. (이때, 많은 문서를 손쉽게 업로드 하기 위해 원도우 탐색기를 이용하여 업로드 하였다.)
그리고, 크로링 작업을 완료 한 후, 검색을 해보았다.
그런데 이때 위 소스에 Author 부분에 아이템의 작성자가 아닌, 이상한 값들이 있는것을 발견!!!

테스트 해 본 결과!!
원도우 탐색기를 열때, 기존의 인증(시스템 계정)이 물려 있었다.
쿠키 및 캐시 때문인가 싶어 지우고도 다시 해보았으나, 처음에 물려있던 인증창이 한번 물리면 안풀린다
(어떻게 해야 풀리는지 찾지는 못함. 단, 어느정도 시간 지나면 풀림)

우선 일차적인 문제는 시스템 계정 인증 문제였으나,
왜 Author에 시스템 계정으로 나오지 않고, 다른 이름이 나오는가 의문을 갖게 되어 찾아본 결과..

시스템 계정 인증으로 Office를 업로드 한 문서를 검색할 경우, 
해당 Office 문서의 만든이로 Author에 등록되어 나온다는 것을 알았다.
그리고 Office 문서가 아닌 이미지와 같은 파일은 시스템 계정으로 나온다.

인증 문제로 인해 다시 삽질을 하지 말자는 바램으로 정리 해보았다.

A while back, I posted a how to on using the KeywordQuery class and it seemed to get pretty good response, so I figured I would post a follow up on how to use the FullTextSqlQuery class today.  It's actually pretty similar to using the KeywordQuery class but of course the syntax is different.  I am not going to give you a full run down of all the syntax, but I will provide enough to get you going. 

There are a number of reason to use the FullTextSqlQuery class.  Using a SQL Syntax query unlocks the full power of Enterprise Search that really isn't there out of the box.  With SQL Syntax, you can do wildcard searches, and make use of the powerful CONTAINS and FREETEXT predicates.  With the CONTAINS predicate, you can use the FORMSOF term to do inflectional (i.e.: go matches going, gone, went, etc.) or thesaurus searches.  Again, check the SDK as there is plenty of documentation about how to use all sorts of predicates.  Before, we look at all the code lets look at a couple of things on the query.

SELECT Title, Path, Color, Size, Quantity, Rank, Description, Size FROM SCOPE() WHERE "scope" = 'My Scope' AND CONTAINS(Description, 'ant*')

In a lot of ways this looks like a T-SQL query.  Enterprise Search queries however always query from SCOPE().  To specify the actual scope (or scopes) you want to search on you use the where clause.  I have always found the syntax weird here because the word scope has to be in quotes and what you are comparing it to always has to be in single quotes.  In this case I am using the CONTAINS predicate to do a wildcard search.  It should return anything that has a word starting with ant in the description column (i.e.: ant, ants, anthony, antler, etc.).

Here is the complete code example.

using (SPSite siteCollection = new SPSite(siteCollectionUrl))

{

    // create a new FullTextSqlQuery class - use property intializers to set query

    FullTextSqlQuery myQuery = new FullTextSqlQuery(siteCollection)

    {

        QueryText = "SELECT Title, Path, Color, Size, Quantity, Description, Rank, Size FROM SCOPE() WHERE \"scope\" = 'My Scope' AND CONTAINS(Color, 'ant*')",

        ResultTypes = ResultType.RelevantResults

    };

 

    // execute the query and load the results into a datatable

    ResultTableCollection queryResults = myQuery.Execute();

    ResultTable queryResultsTable = queryResults[ResultType.RelevantResults];

    DataTable queryDataTable = new DataTable();

    queryDataTable.Load(queryResultsTable, LoadOption.OverwriteChanges);

}

+ Recent posts