I'm struggling with Glass Mapper and can find little on Google. My class has a property that should get all descendant news articles:
[SitecoreQuery(".//*[##templateid='{6F15C485-CA13-4352-A411-7F36447CC879}']", IsRelative = true, IsLazy = true)]
IEnumerable<IArticle> DescendantArticles { get; set; }
There should be about 850 arranged in folders named by year and then by month number but I am only getting 260 results.
I have tried following the query format set out in Tutorial 7:
[SitecoreQuery("./*/*/*[##templateid='{6F15C485-CA13-4352-A411-7F36447CC879}']", IsRelative = true, IsLazy = true)]
Still no dice. If I try:
[SitecoreQuery("./2015/*/*[##te...
I will get all of 2015's articles, so they are all published but when trying to get the lot, I still only get the first 200 articles (2010-2011!). I have tried altering:
<setting name="Query.MaxItems" value="100" />
With no result. I fear I've missed something. Please help!
Since you are running a Sitecore Query the number of items returned is limited by the Query.MaxItems setting:
<!-- Query.MaxItems
Specifies the max number of items in a query result set.
If the number is 0, all items are returned. This may affect system performance, if a
large query result is returned.
This also controls the number of items in Lookup, Multilist and Valuelookup fields.
Default value: 100
-->
<setting name="Query.MaxItems" value="100"/>
This value from Sitecore.config is in turn patched by the setting in Sitecore.ExperienceExplorer.config which sets the value to 260, this was updated in Sitecore 8.1. That is why you only have that many items returned.
Either increase this value or it would be better to reevaluate your code to use ContentSearch API. Turning this value up too high will negatively affect performance.
Related
How can I get the total number of documents matching the given query. I have use the query below:
result = solr.search('ad_id : 20')
print(len(result))
Since the default returning value is '10', the output is only 10, but the count is 4000. How can I get the total number of counts?
The results object from pysolr has a hits property that contains the total number of hits, regardless of how many documents being returned. This is named numFound in the raw response from Solr.
Your solution isn't really suitable for anything with a larger dataset, since it requires you to retrieve all the documents, even if you don't need them or want to show their content.
The count is stored in numFound variable. Use the code below:
result = solr.search('ad_id : 20')
print(result.raw_response['response']['numFound'])
As #MatsLindh mentioned -
result = solr.search('ad_id : 20')
print(result.hits)
Finally got the answer:
Added rows=1000000 at the end of the query.
result = solr.search('ad_id : 20', rows=1000000)
But if the rows are greater than this the number should be changed in the query. This might be a bad solution but works.
If anyone has a better solution please do reply.
If you just want the total number of items that satisfy your query, here is my Python3 code (using the pysolr module):
collection='bookindex' # or whatever your collection is called
solr_url = f"http://{SOLR_HOST}/solr/{collection}"
solr = pysolr.Solr(url=solr_url, timeout=120, always_commit=True)
result = solr.search("*:*", rows=0);
return result.hits
This queries for all documents (":") -- 315913 in my case -- but you can narrow that to suit your requirements. For example, if I want to know how many of my book entries have title:pandas I can search("title:pandas", rows=0) and get 41 as the number that have pandas in the title. By setting rows=0 you're letting Solr know that it need not format any results for you but you just return the meta information, and thus much more efficient than setting a high limit on rows.
I'm using Sitecore 8 MVC .net 4.5. I have boolean field Is Sponsored and I need to order all items such as first with field Is Sponsored = true and by relevance. I found if I add order by Is_Sponsored I'm losing relevance order. So my question is: is there a way to include relevance in existing ordering?
the above method will work fine if you have only a limited amount of documents as you must read all documents from the index.
You can sort by the field SCORE to sort by the sort - so your sort order would be isSponsered, SCORE. This should work as far as I remember - but I have not validated it.
else - more to solr and you will have a number of options to solve this.
You could skip the boolean check in your query and run a regular query with the right relevance order coming back. Then filter down that result set by the boolean value into two separate collections.
var results = queryable.Where(predicate).ToList();
Then:
var sponsored = results.Where(i => i.IsSponsored);
var notSponsored = results.Where(i => !i.IsSponsored);
Then join the collections.
I have two fields that run throughout a website that I would like to match so that when a user inputs a value either of the fields, it will match the other field. I'm using Sitecore Rocks and am trying to use a query to do this.
select ##h1#, ##Title#
from /sitecore/Content/Home//*[##h1# !="##Title#"];
update set ##h1# = ##Title# from /sitecore/Content/Home//*[##Title# = "<id>"];
What am I missing here?
This article talks about tapping in to the item:saving event which allows you to compare the fields values of the item before and after the changes:
http://www.sitecore.net/Community/Technical-Blogs/John-West-Sitecore-Blog/Posts/2010/11/Intercepting-Item-Updates-with-Sitecore.aspx
Using this, you can determine which field has been amended, then change the other to match.
I've had to do something similar to this when a new field was added, and we wanted to set the initial value equal to an existing field. It may be a bug in Sitecore Rocks, but I found it would only update a field when a static value was part of the query.
When I ran ##h1# = ##Title#, the query analyzer would return the correct number of items updated, but no values were actually updated. However, ##h1# = '<id>' worked perfectly. After trying a number of things, I found this did what I wanted.
update set ##h1# = '' + ##Title# from /sitecore/Content/Home//*[##Title# = "<id>"];
I hope that helps.
I have been spending few hours on this issue now, but no luck so far. So reaching out to the community for help.
I have a data template called Product with a field called ProPrice, and some content based on this template I have enabled all fields to be indexed using the configuration <indexAllFields>true</indexAllFields>. When I rebuild the index, I see the index field (proprice) along with the terms stored in Lucene correctly (verified using Luke).
Now I use Sitecore 7 ContentSearch API to fetch content from Lucene index. And for this, I have created a POCO entity called Product, which inherits from SearchResultItem, and have also added a property for price as below:
[IndexField("proprice")]
public double Price { get; set; }
However the following LINQ query does not return any data:
var products = context.GetQueryable<Product>().Where(p => p.Price == 4.0).ToList();
When I look at Sitecore search log, the Lucene query that this translated to was - proprice:[4 TO 4]. And if I execute this query directly against the index in Luke, it returns data. I tried this with other conditions such as p.Price >= 1.0, but none worked. What is interesting is - when I remove the condition and get all records, the Price property in the Product entity is populated with the correct double value (4.0).
But if I change the query slightly as follows, it returns correct data:
var products = context.GetQueryable<Product>().Where(p => p["proprice"] == "4").ToList();
So it looks like when the condition is against numeric values, it does not work. And unfortunately, I need to filter based on a numeric range, and hence the above approach will not work for me. I can avoid ContentSearch API and directly execute the Lucene query using the Lucene provider, but I will not be able to switch to a different search provider, such as Solr, in future. Or alternatively, I can get all data, and then filter in my code - I wouldn't prefer that though.
I would appreciate any help in resolving this.
PS: Few other points:
1) I tried the field type of "ProPrice" in the data template as single line text, integer, double - none worked
2) Am using the default Lucene analyzer - Lucene.Net.Analysis.Standard.StandardAnalyzer
You need to map your index field type to system.double as follows (Notice type="System.Double"):
<field fieldName="proprice" storageType="YES" indexType="TOKENIZED" vectorType="NO" boost="1f" type="System.Double" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider">
<analyzer type="[YOUR ANALYZER]" />
</field>
I think you need the type converter attribute adding to the field. I've done this in my projects and filtering on numbers has worked fine:
So change the property to:
[IndexField("proprice")]
[TypeConverter(typeof(IndexFieldNumberValueConverter))]
public double Price { get; set; }
And you should be able to filter.
I have set caching on a query that is getting run a lot of times.. the query itself is not all that slow, but it get's run many times for each request, so figured caching may help. I have enabled caching, but doesn't really seem to be making a difference.. how do I tell if my query is being cached or not?
I'm setting caching with : q.setCachedWithin("#createTimespan(0, 1, 0, 0)#");
Here is my full query preperation:
q = New Query();
q.setSQL("SELECT * FROM guest_booking WHERE room_id = :roomID and check_in <= :iDate and check_out > :iDate and status != 0");
q.setName("checkAvailability");
q.setCachedWithin("#createTimespan(0, 1, 0, 0)#");
q.addParam(name="iDate", value="#createODBCDate(arguments.date)#", cfsqltype="cf_sql_date");
q.addParam(name="roomID", value="#createODBCDate(arguments.room_id)#", cfsqltype="cf_sql_integer");
qResult = q.execute().getresult();
Debug output is showing:
checkAvailability (Datasource=accom_crm, Time=16ms, Records=1) in C:\ColdFusion9\CustomTags\com\adobe\coldfusion\base.cfc # 16:15:56.056
SELECT * FROM guest_booking WHERE room_id =
?
and check_in <=
?
and check_out >
?
and status != 0
Query Parameter Value(s) -
Parameter #1(cf_sql_integer) = 56
Parameter #2(cf_sql_date) = {ts '2011-11-14 00:00:00'}
Parameter #3(cf_sql_date) = {ts '2011-11-14 00:00:00'}
Many thanks in advance..
Jason
EDIT AFTER SHAWN'S ANSWER BELOW
Have changed the following two lines of query preperation:
query name is now different for differ query.. created dynamically from paramaters passed in
q.setName("check#arguments.room_id##DateFormat(arguments.date,'ddmmyy')#");
createTimeSpan removed from quotes, so not passed in as a string.
q.setCachedWithin(createTimespan(0, 1, 0, 0));
I have also tried sending through an unprepared query (not using addparam(), but just rendering the variables straight in the query string), but made no difference..
EDIT 2 AFTER SHAWN'S 3rd EDITANWSER BELOW
Shawn.. nice pickup on edit 3!!! you have isolated where the problem is. (anyone reading this, quick, up vote Shawn's answer, he found a needle in a hay stack)
Passing the dates in as params does not cache..e.g..
q.setSQL("SELECT booking_id FROM guest_booking WHERE room_id = :roomID and check_in <= :iDate and check_out > :iDate and status != 0");
q.addParam(name="iDate", value="#createODBCDate(arguments.date)#", cfsqltype="cf_sql_date");
Just passing it in as a variable does not cache..e.g..
q.setSQL("SELECT booking_id FROM guest_booking WHERE room_id = :roomID and check_in <= #createODBCDate(arguments.date)# and check_out > #createODBCDate(arguments.date)# and status != 0");
BUT hard coding the dates DOES cache..e.g..
q.setSQL("SELECT booking_id FROM guest_booking WHERE room_id = :roomID and check_in <= {ts '2011-12-16 00:00:00'} and check_out > {ts '2011-12-16 00:00:00'} and status != 0");
This is all good, but clearly I can't hard code the dates... The dates will change for each day obviously, but even where I run the same query with the same dates being passed in dynamically (query syntax being exactly the same), the query won't cache if the dates are passed in as variables.. only if they are hard coded into the query.. wierd.. will keep playing and see what I can find.
Thank you Shawn for pinpointing the problem !!!
If it was correctly cached, your debug output would include just a tiny bit of additional info, to the tune of:
checkAvailability (Datasource=accom_crm, Time=0ms, Records=1, Cached Query)
Something is preventing your query from being cached.
I notice your call to .setCachedWithin() has a string being passed to it-or rather, you're making it a string by qualifying it with quotes, and using # signs.
Try passing the actual value returned from CreateTimeSpan(), without converting it to a string, like so:
q.setCachedWithin(createTimeSpan(0, 1, 0, 0));
-- edit --
Some other tidbits to note about query caching:
The name of the query must be the same.
The SQL statement (in all its parameterized forms) must be the same.
The datasource must be the same.
If used, the username & password must be the same.
The DBTYPE must be the same.
All these attributes must remain the same from call to call in order for ColdFusion to consider it a cache-able query. You mentioned above that you tried taking the addParam() calls out, but still had no luck...
...try using a static query name, rather than one with variables--see if you get any further
q.setName("checkTestQuery");
-- 2nd edit --
Another often overlooked issue is the ColdFusion server's clock. Make sure the CFServer's date/time is set correctly. This may sound silly, but I've seen many a "production" server whose clock was completely off, and not set to the correct timezone, let alone time...and time, of course, is of great significance within the context of caching.
-- 3rd edit --
After re-reading and reviewing everything, I'm going to recommend you take one more look at the 2nd point I made above regarding the SQL statement needing to be the same, and your WHERE clause being dependent upon a variable that is influenced by date/time, which implicitly could change on every request.
...and, since the SQL statement must remain the same in order to be cached, CF discards any attempt to cache it.
Try restructuring the SQL statement temporarily, without the WHERE clause looking for those date variables...and see what it produces.
Shawn's advice is mostly good, but the easiest way to check if the query is being cached is to update the underlying data and see if requerying gives you the previously-cached (all going well) data, or reflects the updates. If it reflects the updates, then it's not being cached...
Note that you don't need to do that horsing around with the query name (as per your update). CF will work out by itself when the parameters are different, and cache separate result sets.