Need help improving this selection and showing all of 'authors' items
Hi guys bit of a code dump but looking for a way to improve the below;
Currently, I take all the news stories on the site, then if the author of the item matches the current page's author (his bio page) I show the articles, ideally you'd have this filter on the selection I think, rather than grabbing all data and then filtering through with an IF.
Part two of this, is that I dont just want news storys, but say items of type newsStoryfeatureblogpost etc what belong to the author, assuming they all have 2 fields in common like title and preview
Okay, so if I was doing something like this, what I would do is create my own Examine index. Call it something like "AuthoredDocumentsIndex". In this index I'd store anything you might be after when searching for these. For example, do all of these Authored documents have article dates as you might want to sort on this.
You can then use Examine to search for all documents where the author = your author.
This would be better than using Site().Descendent, as this will search every single page in your website that is beneath the root. It can, particularly on large websites, become a bottleneck and it is advised to not use Descendent if you can avoid it.
Once you've done your Examine search (which can also order on your date field, and potentially do paging as well), you can then get the typed documents from the Umbraco Cache and render out unique previews for each different doc type if you want to :-)
@{
var searchTerm = "germany";
var searcher = ExamineManager.Instance.SearchProviderCollection["AuthorsSearcher"];
if (searcher == null)
return null;
var searchCriteria = searcher.CreateSearchCriteria(BooleanOperation.Or);
ISearchCriteria query = searchCriteria.RawQuery(searchTerm);
IOrderedEnumerable<SearchResult> searchResults = searcher.Search(query).OrderByDescending(x => x.Score);
return searchResults;
}
Thanks in advance, this is new to me so im probably way off!
edit; error;
Server Error in '/' Application.
Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
Parser Error Message: Expected a "{" but found a "return". Block statements must be enclosed in "{" and "}". You cannot use single-statement control-flow statements in CSHTML pages. For example, the following is not allowed:
@if(isLoggedIn)
<p>Hello, @user</p>
Instead, wrap the contents of the block in "{}":
@if(isLoggedIn) {
<p>Hello, @user</p>
}
Source Error:
Line 76:
Line 77: if (searcher == null)
Line 78: return null;
Line 79:
Line 80: var searchCriteria = searcher.CreateSearchCriteria(BooleanOperation.Or);
Source File: /Views/Author.cshtml Line: 78
@{
var searchTerm = "germany";
var searcher = ExamineManager.Instance.SearchProviderCollection["AuthorsSearcher"];
if (searcher == null)
return null;
var searchCriteria = searcher.CreateSearchCriteria(BooleanOperation.Or);
ISearchCriteria query = searchCriteria.RawQuery(searchTerm);
IOrderedEnumerable<SearchResult> searchResults = searcher.Search(query).OrderByDescending(x => x.Score);
foreach(var searchResult in searchResults.Select(s=> Umbraco.TypedContent(s.Id)))
{
<div>@searchResult.Name</div>
}
}
And error is :
Server Error in '/' Application.
Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
Parser Error Message: Expected a "{" but found a "return". Block statements must be enclosed in "{" and "}". You cannot use single-statement control-flow statements in CSHTML pages. For example, the following is not allowed:
@if(isLoggedIn)
<p>Hello, @user</p>
Instead, wrap the contents of the block in "{}":
@if(isLoggedIn) {
<p>Hello, @user</p>
}
Source Error:
Line 76:
Line 77: if (searcher == null)
Line 78: return null;
Line 79:
Line 80: var searchCriteria = searcher.CreateSearchCriteria(BooleanOperation.Or);
Source File: /Views/Author.cshtml Line: 78
I wasn't sure if I put the code you gave in the right place, whether it should be outside that block or not.
I did just reply Nik but its vanished, so apologies if this appears twice! I still get the error of:
Server Error in '/' Application.
Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
Parser Error Message: Expected a "{" but found a "return". Block statements must be enclosed in "{" and "}". You cannot use single-statement control-flow statements in CSHTML pages. For example, the following is not allowed:
@if(isLoggedIn)
<p>Hello, @user</p>
Instead, wrap the contents of the block in "{}":
@if(isLoggedIn) {
<p>Hello, @user</p>
}
Source Error:
Line 76:
Line 77: if (searcher == null)
Line 78: return null;
Line 79:
Line 80: var searchCriteria = searcher.CreateSearchCriteria(BooleanOperation.Or);
Source File: /Views/Author.cshtml Line: 78
full block is:
@{
var searchTerm = "germany";
var searcher = ExamineManager.Instance.SearchProviderCollection["AuthorsSearcher"];
if (searcher == null)
return null;
var searchCriteria = searcher.CreateSearchCriteria(BooleanOperation.Or);
ISearchCriteria query = searchCriteria.RawQuery(searchTerm);
IOrderedEnumerable<SearchResult> searchResults = searcher.Search(query).OrderByDescending(x => x.Score);
foreach(var searchResult in searchResults.Select(s=> Umbraco.TypedContent(s.Id)))
{
<div>@searchResult.Name</div>
}
}
Just to let you know, your response (at least for me) isn't showing.
But the e-mail notification I got let me see you still have another return statement in there:
return null;
You need to remove this.
Also in Razor, all if statements have to have { } with them. so you can't do
if(searcher == null)
return null;
The reason your reply disappeared I think is a bug. I'm guessing you had this thread open and it automatically loaded my response and you replied to that. If that's the case, don't reply directly to an automatically loaded reply, refresh the page first :-)
Server Error in '/' Application.
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS0103: The name 'BooleanOperation' does not exist in the current context
Source Error:
Line 77:
Line 78:
Line 79: var searchCriteria = searcher.CreateSearchCriteria(BooleanOperation.Or);
Line 80:
Line 81: ISearchCriteria query = searchCriteria.RawQuery(searchTerm);
Edit; adding @using Examine.SearchCriteria; fixed it, but no results, so maybe i need to adjust my search query.
I get no results though, which i guess could mean the search is working but maybe im pointing to the wrong place, I did guess quite heavily on the ExamineIndex and ExamineSettings.
Because the item of 'author' comes out as author: [{"key":"1256","label":"Dudes Name"}] so by searching current authors id of 1256 against that item, it matches. I guess I wasn't sure if I should tell it where to look, or simply remove the things I don't want it to look at. If that makes sense!
So that works, is that all good practice in your eyes?
Personally, I would have the fields I need included in the index, so I'd have the Author, the date you want to search on, the title, the ID, and the nodeTypeAlias.
In case you wanted to extend your searching at any point.
I'd then do my query specifically on the field I want to search against.
Whether this is best practice or not I don't know.
That's cool, do you have any insight or recommended reading on applying the query to a specific field?
I have one last question, how might I order by? I tried editing
IOrderedEnumerable<SearchResult> searchResults = searcher.Search(query).OrderByDescending(x => x.Score); to be something like;
IOrderedEnumerable<SearchResult> searchResults = searcher.Search(query).OrderBy("publishedDate desc"); or .OrderBy("x.publishedDate"); But not having much luck with either!
Without the additional attributes the field won't be sortable by default, and it also won't know how to treat the data in there so will treat it as a string.
Regarding searching a specific field and sorting at the point of query.
var searchCriteria = searchProvider.CreateSearchCriteria(IndexTypes.Content);
var query = searchCriteria.Field("fieldName", searchTerm).And().OrderByDescending("articleDate");
The type arguments for method 'System.Linq.Enumerable.OrderByDescending<TSource,TKey>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,TKey>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Sorry!
If I can just order by then this project is finished, haha. were close I'm sure :D
From some googling I think im still dealing with a string not a date object?
Ive just confirmed this in the back end;
Name: publishedDate, Enable Sorting: true, Type:DateTime
Need help improving this selection and showing all of 'authors' items
Hi guys bit of a code dump but looking for a way to improve the below;
Currently, I take all the news stories on the site, then if the author of the item matches the current page's author (his bio page) I show the articles, ideally you'd have this filter on the selection I think, rather than grabbing all data and then filtering through with an IF.
Part two of this, is that I dont just want news storys, but say items of type
newsStory
feature
blogpost
etc what belong to the author, assuming they all have 2 fields in common liketitle
andpreview
Thanks guys
Hey Kieron,
Okay, so if I was doing something like this, what I would do is create my own Examine index. Call it something like "AuthoredDocumentsIndex". In this index I'd store anything you might be after when searching for these. For example, do all of these Authored documents have article dates as you might want to sort on this.
You can then use Examine to search for all documents where the author = your author.
This would be better than using Site().Descendent, as this will search every single page in your website that is beneath the root. It can, particularly on large websites, become a bottleneck and it is advised to not use Descendent if you can avoid it.
Once you've done your Examine search (which can also order on your date field, and potentially do paging as well), you can then get the typed documents from the Umbraco Cache and render out unique previews for each different doc type if you want to :-)
Thanks,
Nik
This sounded like a good idea so I have attempted, but I'm coming up with an error, here is my code if you wouldn't mind helping out :)
ExamineSettings:
ExamineIndex:
On page in Umbraco:
Thanks in advance, this is new to me so im probably way off!
edit; error;
Yep, you can't use a
Return
statement in your normal Razor code, soreturn searchResults
is causing your error.Replace return searchResults with:
And see if you get a list of document names showing.
Ah yeah that makes sense, so now my block is:
And error is :
I wasn't sure if I put the code you gave in the right place, whether it should be outside that block or not.
Thanks buddy
I did just reply Nik but its vanished, so apologies if this appears twice! I still get the error of:
full block is:
Hey Kieron,
Just to let you know, your response (at least for me) isn't showing.
But the e-mail notification I got let me see you still have another return statement in there:
return null;
You need to remove this.
Also in Razor, all if statements have to have { } with them. so you can't do
The reason your reply disappeared I think is a bug. I'm guessing you had this thread open and it automatically loaded my response and you replied to that. If that's the case, don't reply directly to an automatically loaded reply, refresh the page first :-)
Thanks buddy ill refresh going forward :D
New error, haha.
This is the guide i followed; http://www.jondjones.com/learn-umbraco-cms/umbraco-developers-guide/umbraco-search/how-to-set-up-a-custom-lucene-index-with-umbraco
Thanks for your help!
Edit; adding
@using Examine.SearchCriteria;
fixed it, but no results, so maybe i need to adjust my search query.I get no results though, which i guess could mean the search is working but maybe im pointing to the wrong place, I did guess quite heavily on the ExamineIndex and ExamineSettings.
okay.. so first thing I'd do to check is use the Examine section in the Developer part of the back office.
I'd find the new index in there and check that if you search using the term you are searching for you get results back.
If you get results with that term, you know that your index is populated with values :-)
Thanks this is great insight.
Documents in index
is currently 0, which is probably why its not giving me any back.I wonder if these are affecting it, these items are nested probably 3 levels down. Any ideas? :)
I'd remove
IndexParentId="1"
from your index configuration, then in the back office I'd tell it to rebuild the index.Great, it's going quite well, I've got results now outputting, so Umbraco is currently:
Then to only search for the matching author's items, I actually removed the rest of the data types from the ExamineIndex.config, like so;
Because the item of 'author' comes out as
author: [{"key":"1256","label":"Dudes Name"}]
so by searching current authors id of1256
against that item, it matches. I guess I wasn't sure if I should tell it where to look, or simply remove the things I don't want it to look at. If that makes sense!So that works, is that all good practice in your eyes?
Thanks a bunch
Personally, I would have the fields I need included in the index, so I'd have the Author, the date you want to search on, the title, the ID, and the nodeTypeAlias.
In case you wanted to extend your searching at any point.
I'd then do my query specifically on the field I want to search against.
Whether this is best practice or not I don't know.
That's cool, do you have any insight or recommended reading on applying the query to a specific field?
I have one last question, how might I order by? I tried editing
IOrderedEnumerable<SearchResult> searchResults = searcher.Search(query).OrderByDescending(x => x.Score);
to be something like;IOrderedEnumerable<SearchResult> searchResults = searcher.Search(query).OrderBy("publishedDate desc");
or.OrderBy("x.publishedDate");
But not having much luck with either!Thanks very much for your help.
Okay, regarding sorting:
Change your entry in your index for the date field to:
Without the additional attributes the field won't be sortable by default, and it also won't know how to treat the data in there so will treat it as a string.
Regarding searching a specific field and sorting at the point of query.
Then you perform the search by doing:
Ok, thank you, sorry I know this has taken a while but I am struggling to merge the new code in, I have this;
But i am getting:
The name 'IndexTypes' does not exist in the current context
I have avoided the field targeting because I was a bit overwhelmed, lol.
Thank you
You are missing this namespace :-)
That will give you access to the
IndexTypes
enumThat was it, however...
The type arguments for method 'System.Linq.Enumerable.OrderByDescending<TSource,TKey>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,TKey>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Sorry!
If I can just order by then this project is finished, haha. were close I'm sure :D
From some googling I think im still dealing with a string not a date object?
Ive just confirmed this in the back end;
Name: publishedDate, Enable Sorting: true, Type:DateTime
Any ideas?
Hi Kieron,
Yep, I think it's because the way you are trying to do the ordering isn't using Examine it's using Linq.
To achieve ordering the way you are going about it I think you'll need to do something like
(I've not tested this and off the top of my head I can't remember how you access a field on a search result but I think that is about right.
Thanks
Nik
Thats perfect (except for one letter*) Nik thanks so much for your help and patience :D
*PS, Field needs to be Fields
Thanks again
No worries at all :-) Happy to help.
is working on a reply...