Question : How to target search core results to an audience

I have a list that has audience targeting on the items.  I would like to be able to limit the results of a search to those items to which the user is targeted.  I have the search page setup already to limit scope to this list.  Example:

Item 1 -- East of Eden -- Target: Writers
Item 2 -- Witches of Eastwick -- Target: Directors

When a member of the "Writers" group searches for the word "East", I only want Item 1 to be returned.  Similarly, when a member of the "Directors" group searches for the same word "East", I only want Item 2 returned.

Can this be done?

Answer : How to target search core results to an audience

For future reference, I solved this by creating a custom CoreResultsWebPart.  I have included the code here with some comments.  Much is specific to my personal need, so take from it what you want.  The XSL code is for the most part the default XSL that I pulled from the Search Core Results webpart.  One thing I noticed was, for some reason, their XSL did not capitalize the field names.  Turned out to be case sensitive.  I could have just .ToLower'ed everything, but I decided to change the XSL instead.  I also left in the commented out XSL that will display all values returned.  I found it useful during debugging and figured someone else would, too.

Hope this helps someone else in the future.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
using System;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.XPath;
using Microsoft.Office.Server;
using Microsoft.Office.Server.Audience;
using Microsoft.Office.Server.Search.Query;
using Microsoft.Office.Server.Search.WebControls;
using Microsoft.Office.Server.WebControls;
using Microsoft.SharePoint;
 
namespace KBSearchWebPart
{
 
    [ToolboxData("<{0}:CoreResultsWebPart runat=server>")]
    
    public class KBSearch : CoreResultsWebPart
    {
 
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            string strQueryText = string.Empty;
            if (Page.Request["k"] != null)
                {
                    strQueryText = Page.Request["k"].ToString();
                }
            if (strQueryText != string.Empty && strQueryText != null)
            {
 
                keywordQueryExecute(strQueryText);
                this.Xsl = @"
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
 
                    
                    
                      
                      
                      
                          
                      
                       
                          
                       
                      
                             
                    
 
 
                    
                    
                     
                     


- Bytes KB MB -
[ ]
"; // this.Xsl = @" // // // // // <xsl:copy-of select=""*""/> // // // "; } else { XmlDataSource source = new XmlDataSource(); source.Data = ""; this.DataSource = source; } this.DataBind(); } //this is required due to a bug in using XML as the datasource for a dataformwebpart protected override XPathNavigator GetXPathNavigator(string viewPath) { XmlDocument doc = new XmlDocument(); doc.LoadXml(((XmlDataSource)this.DataSource).Data.ToString()); return doc.CreateNavigator(); } private void keywordQueryExecute(string strQueryText) { KeywordQuery kRequest = new KeywordQuery(ServerContext.Current); kRequest.QueryText = strQueryText; //only want to search on this list, don't want it to be modified on web part page kRequest.HiddenConstraints = "scope:" + "\"IT Knowledge Base Search\""; kRequest.ResultTypes = ResultType.RelevantResults; ResultTableCollection resultTbls = kRequest.Execute(); if ((int)ResultType.RelevantResults != 0) { ResultTable tblResult = resultTbls[ResultType.RelevantResults]; DataTable relResultsTbl = new DataTable(); relResultsTbl.TableName = "Result"; DataSet ds = new DataSet("All_Results"); ds.Tables.Add(relResultsTbl); ds.Load(tblResult, LoadOption.OverwriteChanges, relResultsTbl); displayResults(ds); } } private void displayResults(DataSet grdDs) { DataSet dsFiltered = grdDs.Clone(); foreach (DataRow relevantResult in grdDs.Tables["Result"].Rows) { //The Magic happens here. pulls the list ID from the URL using Regex //and then pulls up the list item, checks if current user is in //the audience, and returns results if so String itemURL = relevantResult["Path"].ToString(); Regex r = new Regex(@"(id=)\S*", RegexOptions.IgnoreCase); Match m = r.Match(itemURL); if (m.Success) { Regex r2 = new Regex(@"(id=)", RegexOptions.IgnoreCase); Int32 itemID = Convert.ToInt32(r2.Replace(m.Groups[0].Value.ToString(), "")); using (SPWeb owebsite = SPContext.Current.Site.AllWebs["informationtechnology"]) { //GUID of my KB list Guid listid = new Guid("07198824-2397-40c6-b6d1-31ff016bb1c3"); SPList olist = owebsite.Lists.GetList(listid, false); SPListItem olistitem = olist.GetItemById(itemID); AudienceLoader audienceLoader = AudienceLoader.GetAudienceLoader(); String strAudienceList = (string)olistitem["Target_x0020_Audiences"]; if (AudienceManager.IsCurrentUserInAudienceOf(audienceLoader, strAudienceList, false) || strAudienceList == string.Empty) { DataRow dr = dsFiltered.Tables["Result"].NewRow(); dr.ItemArray = relevantResult.ItemArray; dsFiltered.Tables["Result"].Rows.Add(dr); } } m.NextMatch(); } } StringWriter writer = new StringWriter(); XmlWriterSettings xmlSettings = new XmlWriterSettings(); xmlSettings.OmitXmlDeclaration = true; xmlSettings.Indent = true; xmlSettings.IndentChars = "\t"; xmlSettings.NewLineHandling = NewLineHandling.Entitize; xmlSettings.NewLineChars = Environment.NewLine; XmlWriter xmlResultWriter = XmlWriter.Create(writer, xmlSettings); dsFiltered.WriteXml(xmlResultWriter, XmlWriteMode.IgnoreSchema); XmlDataSource dataSource = new XmlDataSource(); string strData = writer.ToString(); //cleanup of data strData = Regex.Replace(strData,"<","<"); strData = Regex.Replace(strData,">", ">"); strData = Regex.Replace(strData, "amp;", ""); dataSource.Data = strData; dataSource.DataBind(); xmlResultWriter.Close(); this.DataSource = dataSource; } } }
Random Solutions  
 
programming4us programming4us