Solr Schemaless Mode creating fields as MultiValued - indexing

I'm using Solr 6.1 in Schemaless Mode. After creating a collection and indexing a sample data the fields created were all set to have MultiValued = true, except for unique id.
The problem is when querying this data using SolrNet it wouldn't map the result to the model correctly. The queried results is returned as an array and require all my properties in the model to be updated to ICollection type.
Is there anyway we can set these field to MultiValued = false when indexing the sample data?
An example to illustrate the problem:
1) Index a sample of the following model in Schemaless Mode:
public class TestModel
{
[SolrUniqueKey("id")]
public int Id { get; set; }
[SolrField("guid")]
public Guid Guid { get; set; }
}
2) Solr's managed-schema file will be added with the following fields
<field name="guid" type="strings"/>
<field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/>
3) Error during querying / mapping of the model
Object of type 'System.Collections.ArrayList' cannot be converted to type

The schemaless mode makes everything multiValued as it does not know if you have single values followed by multivalued values for the same field. So it makes all fields multivalued and also upgrades numeric types to the largest.
This is easily adjustable if you know your domain well. The whole mapping chain is defined in the solrconfig.xml's update request processor chain (add-unknown-fields-to-the-schema) and you can change the type mapping from multivalued type to an equivalent single valued type. For strings, you change the value in the defaultFieldType.

Related

Apache Solr - Document is missing mandatory uniqueKey field: id

I'm using Solr7.1 (SolrCloud mode) and I don't have requirement to enforce document uniqueness.
Hence I marked id field (designated as unique key) in schema as required="false".
<field name="id" type="string" indexed="true" stored="false" required="false" multiValued="false" />
<uniqueKey>id</uniqueKey>
And I am trying to index some documents using solr Admin UI and I am trying without specifying 'id' field.
{
"cat": "books",
"name": "JayStore"
}
I was expecting it to index successfully but solr is throwing error saying 'mandatory unique key field id is missing'
Could some one guide me what I'm doing wrong.
The uniqueKey field is required internally by Solr for certain features, such as using cursorMark - meaning that the field that is defined as a uniqueKey is required. It's also used for routing etc. inside SolrCloud by default (IIRC), so if it's not present Solr won't be able to shard your documents correctly. Setting it as not required in the schema won't relax that requirement.
But you can work around this by defining an UUID field, and using a UUID Update Processor as described in the old wiki. This will generate a unique UUID for each document when you index it, meaning each document will get a unique identificator attached by default.
UUID is short for Universal Unique IDentifier. The UUID standard RFC-4122 includes several types of UUID with different input formats. There is a UUID field type (called UUIDField) in Solr 1.4 which implements version 4. Fields are defined in the schema.xml file with:
<fieldType name="uuid" class="solr.UUIDField" indexed="true" />
in Solr 4, this field must be populated via solr.UUIDUpdateProcessorFactory.
<field name="id" type="uuid" indexed="true" stored="true" required="true"/>
<updateRequestProcessorChain name="uuid">
<processor class="solr.UUIDUpdateProcessorFactory">
<str name="fieldName">id</str>
</processor>
<processor class="solr.RunUpdateProcessorFactory" /
</updateRequestProcessorChain>

How to add null value to field Many2one from data file Odoo

I want to add a new category of Salary Structure by data file. Here is my current code
<record id="MEALS" model="hr.salary.rule.category">
<field name="name">Meals</field>
<field name="code">MEALS</field>
<field name="parent_id" eval=""></field>
</record>
All I need is a category with no parent category but with these code parent category of it is Base for new structures. I've tried with evals="0", evals = " " or remove field parent_id out of .How can I add null value into this field ?
This behaviour is a little weird .AFAIK If you don't include the parent_id field, it should work and have a null value because that field doesn't have a default value on it. (Except you've extended the model and added a default on that field).
The only fields where null values don't work in the Odoo ORM are Integer and float fields. (That's the reason they always have an initial value of 0 or 0.0 in a form view).
quoting the docs:
field
Each record can be composed of field tags, defining values to
set when creating the record. A record with no field will use all
default values (creation) or do nothing (update).
A field has a mandatory name attribute, the name of the field to set,
and various methods to define the value itself:
Nothing
if no value is provided for the field, an implicit False will
be set on the field. Can be used to clear a field, or avoid using a
default value for the field.
Try this <field name="parent_id" /> or <field name="parent_id" eval="False" />
If the above don't work then double check your codebase and make sure you're not setting any default value on the field.

When does SPMetal generate EntityRef properties for lookup fields?

I have a defined a content type called SPVideoDataItem containing those two fields:
<Field ID="{487F2AD6-D9D6-47AA-AA99-B3FFF893E689}" Name="LUVideoQuality" Group="Custom Columns" Type="Lookup" DisplayName="Video Quality" List="Lists/GlobalVideoQualityList" ShowField="Title" PrependId="TRUE" ShowInEditForm="TRUE" ShowInNewForm="TRUE"/>
<Field ID="{F348A825-764D-41EE-AF92-8CF1DC246E47}" Name="LUVideoTitle" Group="Custom Columns" Type="Lookup" DisplayName="Video Title" List="Lists/VideoItemList" ShowInEditForm="TRUE" ShowInNewForm="TRUE" ShowField="VideoItemTitle" PrependId="TRUE" Required="TRUE"/>
For LUVideoQuality I get a property in a class called VideoItemDataListSPVideoDataItem:
public SPVideoQualityItem VideoQuality
which exposes a EntityRef-Member, so I can access all properties of SPVideoQualityItem.
However, for LUVideoTitle spmetal just generates two properties in the parent class SPVideoDataItem
public string VideoTitleVideoItemTitle
public System.Nullable<int> VideoTitleId
where I can only access title and ID.
I wonder why spmetal handles this two lookups differently. Can anyone explain this behaviour? I would prefer that all lookups are handled like LUVideoQuality in my example.
I've encountered the same issue.
When I let go of the principle to create a separate content type and just created a list based on content type Item it did generate the entity refs.
Apparently it has something to do with the "WebId" property of the lookup fields. A colleague told me that they got it working by adding
WebId="~sitecollection"
to all lookup fields in the content type definitions (Elements.xml). Im not marking this as an answer because I did not check if it is working now because of this attribute or some other change in the definitions.

What is the use of "multiValued" field type in Solr?

I'm new to Apache Solr. Even after reading the documentation part, I'm finding it difficult to clearly understand the functionality and use of the multiValued field type property.
What internally Solr does/treats/handles a field that is marked as multiValued?
What is the difference in indexing in Solr between a field that is multiValued and those that are not?
Can somebody explain with some good example?
Doc says:
multiValued=true|false
True if this
field may contain multiple values per
document, i.e. if it can appear
multiple times in a document
A multivalued field is useful when there are more than one value present for the field. An easy example would be tags, there can be multiple tags that need to be indexed. so if we have tags field as multivalued then solr response will return a list instead of a string value. One point to note is that you need to submit multiple lines for each value of the tags like:
<field name="tags">tag1</tags>
<field name="tags">tag2</tags>
...
<field name="tags">tagn</tags>
Once you have all the values index you can search or filter results by any value, e,g. you can find all documents with tag1 using query like
q=tags:tag1
or use the tags to filter out results like
q=query&fq=tags:tag1
multiValued defined in the schema whether the field is allowed to have more than one value.
For instance:
if I have a fieldType called ID which is multiValued=false indexing a document such as this:
doc {
id : [ 1, 2]
...
}
would cause an exception to be thrown in the indexing thread and the document will not be indexed (schema validation will fail).
On the other hand if I do have multiple values for a field I would want to set multiValued=true in order to guarantee that indexing is done correctly, for example:
doc {
id : 1
keywords: [ hello, world ]
...
}
In this case you would define "keywords" as a multiValued field.
I use multiple value fields only with copyfields, so think this way, say all fields will be single valued unless it's a copyfield, for example I have following fields:
<field name="id" type="string" indexed="true" stored="true"/>
<field name="name" type="string" indexed="true" stored="true"/>
<field name="subject" type="string" indexed="true" stored="true"/>
<field name="location" type="string" indexed="true" stored="true"/>
I want to query one field only and possibly to search all 4 fields above, then we need to use copyfield. first to create a new field call 'all', then copy everything into 'all'
<field name="all" type="text" indexed="true" stored="true" multiValued="true"/>
<copyField source="*" dest="all"/>
Now field 'all' need to be multi-valued.

Automatically truncating strings in NHibernate / SQL Server

I have a nvarchar(2000) column in a SQL Server 2005 database, and have mapped this into NHibernate as:
<property name="Query" column="`Query`" type="String" length="2000" not-null="false"/>
The DTO class just presents a string property:
public virtual string Query { get; set; }
If I set the query to a string of > 2000 characters I get an exception from SQL server to the effect of:
"String or binary data would be
truncated. The statement has been
terminated."
What I want is for this truncation to just happen automatically and silently. I could override the virtual property and force the truncation on the property set, but feel there should be a way to get this behaviour by default, either via the NHibernate mapping or even as a SQL server setting.
Am I missing anything ... I don't want to change the db schema to allow longer strings.
Create a custom User Type and which truncates the string if it's longer than 2000 chars. Here is sample of creating User Type
<property name="Query" type="Common.Nhibernate.Types.StringTruncType, Common" column="`Query`" type="String" length="2000" not-null="false"/>