简体   繁体   English

如何在全文搜索中使用CROSS APPLY的结果

[英]How to use result of CROSS APPLY in Full-Text search

I want to use the result of CROSS APPLY in full-text search ( FREETEXT or CONTAINS ) like this: 我想在全文搜索( FREETEXTCONTAINS )中使用CROSS APPLY的结果,如下所示:

   SELECT  p.Id ,
            p.Name ,
            p.ShortDescription ,
            p.DisplayOrder ,
            cat.Name AS CategoryName
    FROM    dbo.Product AS p
            CROSS APPLY ( SELECT TOP 1
                                    c.Name ,
                                    c.Description ,
                                    c.Id
                          FROM      dbo.Product_Category_Mapping AS m
                                    LEFT JOIN dbo.Category AS c ON m.CategoryId = c.Id
                          WHERE     m.ProductId = p.Id
                                    AND c.Published = 1
                                    AND c.Deleted = 0
                        ) AS cat
    WHERE   p.Published = 1
            AND p.Deleted = 0
            AND ( CONTAINS ( p.NAME, @search )
                  OR CONTAINS ( p.FullDescription, @search )
                  OR CONTAINS ( cat.NAME, @search )
                );

My problem is ==> OR CONTAINS ( cat.Name, @search ) . 我的问题是==> OR CONTAINS ( cat.Name, @search ) The error returned by SQL Server is: SQL Server返回的错误是:

Cannot use a CONTAINS or FREETEXT predicate on column 'Name' because it is not full-text indexed. 无法在“名称”列上使用CONTAINS或FREETEXT谓词,因为它不是全文索引。

It seems the result of CROSS APPLY is a table and this table is not full-text indexed. 似乎CROSS APPLY的结果是一个表,并且该表没有全文索引。 How can I apply the full-text index search condition to the result of the CROSS APPLY above? 如何将全文索引搜索条件应用于上面的“ CROSS APPLY ”结果?

Try something like this: 尝试这样的事情:

SELECT  p.Id ,
            p.Name ,
            p.ShortDescription ,
            p.DisplayOrder ,
            cat.Name AS CategoryName
    FROM    dbo.Product AS p
            CROSS APPLY ( SELECT TOP 1
                                    c.Name ,
                                    c.Description ,
                                    c.Id
                          FROM      dbo.Product_Category_Mapping AS m
                                    LEFT JOIN dbo.Category AS c ON m.CategoryId = c.Id
                          WHERE     m.ProductId = p.Id
                                    AND c.Published = 1
                                    AND c.Deleted = 0
                        ) AS cat
    LEFT JOIN dbo.Category cat2 ON cat2.Id = cat.Id
    WHERE   p.Published = 1
            AND p.Deleted = 0
            AND ( CONTAINS ( p.NAME, @search )
                  OR CONTAINS ( p.FullDescription, @search )
                  OR CONTAINS ( cat2.NAME, @search )
                );

Note, I have re-joined dbo.Category on main level and have changed CONTAINS predicate to reference cat2.NAME instead of cat.Name . 请注意,我已经在主要级别上重新加入dbo.Category ,并将CONTAINS谓词更改为引用cat2.NAME而不是cat.Name cat is the CROSS JOIN alias which indeed is not under full text-index, but the main dbo.Category table aliased under cat2 IS under full-text index, so you can use its column NAME with CONTAINS . catCROSS JOIN别名,它的确不在全文索引下,而是在dbo.Category别名下的主dbo.Category表在全文索引下位于IS,因此您可以将其列NAMECONTAINS

Also, I think it would be better if you re-write your query and move the CONTAINS checks inside the CROSS JOIN like this: 另外,我认为最好重写查询并在CROSS JOIN移动CONTAINS检查,如下所示:

SELECT  p.Id ,
            p.Name ,
            p.ShortDescription ,
            p.DisplayOrder ,
            cat.Name AS CategoryName
    FROM    dbo.Product AS p
            CROSS APPLY (
                SELECT TOP 1
                    c.Name ,
                    c.Description ,
                    c.Id,
                    (CASE WHEN CONTAINS(cat.NAME, @search) THEN 1 ELSE 0 END) as IsCategoryMatching
                FROM      dbo.Product_Category_Mapping AS m
                LEFT JOIN dbo.Category AS c ON m.CategoryId = c.Id
                WHERE m.ProductId = p.Id
                      AND c.Published = 1
                      AND c.Deleted = 0
            ) AS cat    
    WHERE   p.Published = 1
            AND p.Deleted = 0
            AND ( CONTAINS ( p.NAME, @search )
                  OR CONTAINS ( p.FullDescription, @search )
                  OR cat.IsCategoryMatching=1
                );

HTH 高温超导

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM