I have created a new object, set the values (including the ID/PK) but when I use qx::dao::insert, it ignores the ID I have specified.
How can I specify the PK value of the row I want to persist?
I think you have defined your primary key as auto-increment (this is the default value for numeric types with QxOrm library).
If you want to define the primary key yourself before inserting an instance to database, register your ID like this :
template <>
void register_class(QxClass<MyClass> & t)
{
qx::IxDataMember * pId = t.id(& MyClass::m_my_id, "my_id");
pId->setAutoIncrement(false);
// etc...
}
Related
I have a table Documents and it has a field named type and the type has two data's namely - type1 & type2
Now my requirements is - i have a bootstrap tabs type1 & type2, and i need to display data accordingly on the template
Which is efficient way to do this ?
Using two variables
data = Documents.objects.filter(id=pk)
type1 = data.filter(type="type1")
type2 = data.filter(type="type2")
and then pass it to context
context = { "type1":type1,"type2":type2 }
Is there any other best way to do this ?
Seems like they really have to be different querysets since they are different sets of data to be rendered. Also assuming id is your primary key (which looks like it is), note that the usage of Documents.objects.filter(id=pk).filter(type=...) would just consider that 1 object with that pk, you might want to change it to Documents.objects.filter(type=...). Then you can make it a bit more dynamic by listing the possible types and then passing the filtered data to the template where the key is the type.
doc_types = ("type1", "type2")
context = {
doc_type: Documents.objects.filter(type=doc_type)
for doc_type in doc_types
}
According to the EMF FAQ, it is possible to create a Map in EMF:
An EMap is basically a List of java.util.Map$Entry instances.
Therefore to create a Map you need to first model your map entry by
following these steps:
Create an EClass with the name [Type1]To[Type2]Map where [Type1] represents the key's type and the [Type2] represents the value's type.
Set the Instance Class Name property of the newly created EClass to java.util.Map$Entry.
Create an EAttribute or EReference named "key" and set the EDataType or EClass for it.
Create an EAttribute or EReference called "value" and set the EDataType or EClass for it.
Now, when you create an EReference somewhere that uses this map entry
class as its EClass, the EMF code generator will detect this special
case and generate a properly typed EMap getter/setter for you instead
of a normal EList getter/setter.
Can I use this with Xcore models? I am not sure whether step #2 is doable in Xcore or whether it supports maps at all.
For me this works.
DataPoints.xcore:
...
class KeyValuePair wraps java.util.Map$Entry {
String key
String value
}
class KeyValueList {
contains KeyValuePair[] entries
}
The above results in a KeyValueListImpl class with a getEntries method that looks like this:
public EMap<String, String> getEntries() {
if (entries == null) {
entries = new EcoreEMap<String,String>(DataPointsPackage.Literals.KEY_VALUE_PAIR, KeyValuePairImpl.class, this, DataPointsPackage.KEY_VALUE_LIST__ENTRIES);
}
return entries;
}
I have a IQueryable<T> object as search results object.
I apply the filtering and sorting on this search object.
Before I call the GetResults(), I want to order the results based on one of the field's (Fieldname - Priority) value. So for all the items in the IQueryable<T> object, I want to order them desc by Priority field, so all the items which has a value for that field stay at the top and the rest are at the bottom.
I have the fieldmap entry for Priority field.
search.OrderByDescending(i => !string.IsNullOrEmpty(i.GetItem().GetFieldValue("Priority")))
The above command doesn't work. Apparently, I can't use Sitecore extension methods with IQueryable?
If I convert search.ToList(). Do the ordering and then convert it back to AsQueryable(), I get the following error:
There is no method 'GetResults' on type 'Sitecore.ContentSearch.Linq.QueryableExtensions'
that matches the specified arguments
Is there a neat and quick way to get around this?
Cheers
I think you just need to add your field to your SearchResultItem and mark it as an int. I am making the assumption that the field is an int. Make a custom class that inherits SearchResultItem.
public class CustomSearchResultItem : SearchResultItem
{
[IndexField("Priority")]
public int Priority { get; set; }
}
Then use it in your search. Finally order by it.
using (var context = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
var results = context.GetQueryable<CustomSearchResultItem>().Where(prod => prod.Content.Contains("search box text").OrderByDescending(t => t.Priority);
}
Some data found here.
http://www.sitecore.net/learn/blogs/technical-blogs/sitecore-7-development-team/posts/2013/10/sorting-and-ordering-results.aspx
You can order search results using multiple fields by using the OrderByDescending combined with ThenByDescending. So you would need to order by Priority and then by [Name|Date|Whatever].
I want to order them desc by Priority field, so all the items which has a value for that field stay at the top and the rest are at the bottom.
I sort them first on the criteria chosen by the user - like Name, Date created etc. Once I get the results back, I need to order them by priority field
You are conflicting yourself in the questions and comments. If you want the results with priority first and then by user selected results then the following will work:
query = dataQuery.OrderByDescending(i => i.Title).ThenByDescending(i => i["Priority"]);
var results = query.GetResults().Hits.Select(h => h.Document);
There was a bug in earlier version of Sitecore which meant that the ThenBy clause will be added before the OrderBy clause hence it is added in reverse above. You may want to check if this is fixed in the current version. If so simply change your query to:
query = dataQuery.OrderByDescending(i => i["Priority"]).ThenByDescending(i => i.Title);
You don't have to add the field to your SearchResultItem if you just want to order by it, only if you need the actual value of that field returned to as well.
If you need to order by a custom user supplied value then you can pass in i => i["whatever-field-the-user-has-selected"] instead of i.Title.
You can find more info in this blog post.
I have a use case in which users need to select a field value from a droplist of items. The problem with this is that the droplist needs to be dynamically built on each item (all with the same template) to only show items in a folder that have a field value equal to that of the current item's ID. In case you're already lost, here's an example of the structure:
- sitecore
- content
- Home
- ContentItem1 (with droplist)
- Site Data
- SelectableItem1(ContentItem1 selected in 'itemid' field)
- SelectableItem2(ContentItem1 selected in 'itemid' field)
- SelectableItem3(ContentItem1 not selected in 'itemid' field)
- SelectableItem4(ContentItem1 not selected in 'itemid' field)
- templates
- ContentItem1Template
- Droplist field (source set to below query)
I want my query to assign the ContentItem1's droplist field source dynamically by getting a list of items that have ContentItem1's id as their 'itemid' field's value, but by comparing the field value to that of the ContentItem1 id. I have tried doing this by comparing the field's value to the id token, like so:
query:/sitecore/content/Site Data/*[##itemid#=$id]
No matter what value I try for id ('$id', $id, #id, '#id', ##id, '##id', etc.) it does not want to resolve on the item level. Is there some way to do this so that I can reuse this ContentItem1Template for all of my items that need the same functionality?
If you are using Sitecore 7 then you can use coded field datasources. This will allow you to use any custom logic you like to specify the items which should appear in your lists.
Create a class that implements IDataSource and the ListQuery() method that returns a list of Items as the source of your field. Then set the source of your field to your method with the code: prefix, e.g. code:MyProject.Custom.FieldDataSource,MyProject.Custom
using System;
using Sitecore.Buckets.FieldTypes;
using Sitecore.Data.Items;
namespace MyProject.Custom
{
public class FieldDataSource : IDataSource
{
public Item[] ListQuery(Item item)
{
var root = item.Database.GetItem("/sitecore/content/my-item");
// some other logic to filter your item set
return root.Children.ToArray();
}
}
}
These articles should help you:
Custom Classes as Data Template Field Sources
Having code as your field its datasource
You may need to wrap the ID in single quotes like so:
query:/sitecore/content/#Site Data#/*[#itemid='$id']
That said, this seems like a good fit for using the Sitecore Link Database. Whenever you associate a SelectableItem to a ContentItem, Sitecore will store that relationship in the Link database (as long as you reference it using a field that supports it, such as a DropLink, DropTree, GeneralLink, etc.).
From there, you can use Globals.LinkDatabase.GetReferrers(contentItem) or contentItem.Links.GetValidLinks() to get a list of all referring items to the content item. This is where you can filter down the list by template ID to ensure that you only return SelectableItems.
I have a unique ID field of type int in my documents. I'm doing ensureIndex on this field, but my documents still contain _id. Can I get rid of it?
From the docs ...
If a user tries to insert a document without providing an _id field,
the database will automatically generate an object id and store it
the _id field.
However, you can assign your own value to _id ...
The _id value may be of any type, other than arrays, so long as it is
a unique.
The better question is why would you create your own unique ID, build an index on it and remove the very useful ObjectID _id that is auto indexed?
All the official drivers use ObjectID and it has a lot of really good aspects to it:
It has a timestamp built in (so you don't need to store a date field
in your document, and you can use it to order by date.)
It is a "global, uniformly increasing sequence number" --- i.e.
it'll still be unique across servers if you need to shard your data,
etc.
No, you can't get rid of it, it is there by design, but you can map your unique identifier int to the _id itself when inserting documents.
A good idea would to store your hash into the _id field.
Thus, the database won't create automatically the _id field because it will already exist and you will save the space of an unused index.
Just set the _id field as any other with the value you want (your hash for instance). But be careful, it needs to be unique !
To ensure unicity you should either make it unique or put a subdocument in the _id field :
{ _id : { h : [yourHash], u : [a unique identifier]} , ...}