MarkLogic: Having facet results be case-insensitive - xquery

I have a constraint based on an XML path range index, that is returning facet values for different types of letter casing:
<facet name="myFacet" type="xs:string">
<facet-value name="test TEST" count="1"/>
<facet-value name="Test Test" count="3"/>
</facet>
I want my facet values to be case insensitive, to where the above I would have 4 results for "Test Test". Is there a way of easily setting this in the options, the below I have is not working:
<constraint name="myFacet">
<range type="xs:string" facet="true">
<path-index>/path/to/data</path-index>
<word>
<term-option>case-insensitive</term-option>
</word>
</range>
</constraint>
Without manually lowercasing each item in the field in the data itself, is there a way to achieve this with a search option I can pass into the constraint?

You have to create a string index that uses a collation which includes the case-insensitive flag. You then refer to that string index as usual, but with the extra collation.
I recommend looking at the Admin ui, open the path indexes page of your database, create one of type string, and look for the collation builder button. It should pop up a little wizard that helps you compose the collation you need.
HTH!

Related

Jaspersoft Studio - Create collection of Strings

Using Jaspersoft Studio 6.4.
I am trying to create a java.util.Collection, with nested type java.lang.String.
I want to populate the collection with the values from my data query: iterate through the values of the Field $F{CostCenter} and add each value to my collection. (My query is a domain query).
I have tried
Creating a collection variable
Incrementing the variable by my CostCenter group
Adding the field value to my variable
<variable name="dls_CCArray" class="java.util.Collection" incrementType="Group" incrementGroup="CCGroup">
<variableExpression><![CDATA[$V{dls_CCArray}.add( $F{costCenterSet.costCenterConcatenated} )]]>
</variableExpression>
</variable>
But my variable is null, even though i know my query is returning cost centers.
Reason I need to do this: I have an optional input control. When i select no cost centers, i still need to pass the list of cost center values returned by the query to my next report through my hyperlink parameter.
Thanks in advance
You can use a second variable to add the value to the collection variable. Also, since the engine might evaluate variable expressions more than once, it would be safer to collect the values in a Set so that you don't end up with duplicate values.
Therefore you could have something like this:
<variable name="Values" class="java.util.Set" calculation="System">
<initialValueExpression>new java.util.HashSet()</initialValueExpression>
</variable>
<variable name="ValueAdd" class="java.lang.Boolean">
<variableExpression>$V{Values}.add($F{costCenterSet.costCenterConcatenated})</variableExpression>
</variable>

How to know the distinct namespaces in a database in MarkLogic?

I have a database in MarkLogic server. The database has many collections. Some of these collections have a namespace and some have different namespace. What is the query to know the distinct namespaces? My goal is to build a search application that would allow users to use a search bar and have the documents returned from the most relevant collections. Since all the collections have different xml structure I also want to customize the display of the documents base on the collection and search.
However you question is not clear to me but if you want to get all unique namespace from your DB you may run:
fn:distinct-values(//namespace-uri())
and if you want to get all unique collection from DB (on collection lexion of the DB):
cts:collections()
and if you want to perform search on particular collection only:
in search:search use:
<additional-query>{cts:collection-query('collectionName')}</additional-query>
in cts:search use:
cts:collection-query(("reports", "analysis")))
One way to get the list of unique collections in a database is to use the App Services Search API. You can specify a collection constraint in the search options which will return the unique collections. The example below specifies a collection constraint without a prefix, then returns a list of the facet values with the number of documents counted for each collection.
(: insert test documents here :)
xquery version "1.0-ml";
for $i in 0 to 5
let $collection := "https://example.com/" || $i
for $j in 0 to $i
return xdmp:document-insert("/example-doc/" || $i || "-" || $j, <example/>, (), $collection);
(: Use search API to get collections as a facet :)
xquery version "1.0-ml";
import module namespace search =
"http://marklogic.com/appservices/search"
at "/MarkLogic/appservices/search/search.xqy";
(: build a collection constraint facet :)
let $options :=
<options xmlns="http://marklogic.com/appservices/search">
<constraint name="collections">
<collection prefix="" facet="true" />
</constraint>
</options>
(: return facets ordered by the number of documents in each collection :)
let $facets := search:search("", $options)/search:facet/search:facet-value
for $facet in $facets
order by $facet/#count descending
return (element collection {($facet/#name, $facet/#count)})
Returning:
<collection name="https://example.com/5" count="6"/>
<collection name="https://example.com/4" count="5"/>
<collection name="https://example.com/3" count="4"/>
<collection name="https://example.com/2" count="3"/>
<collection name="https://example.com/1" count="2"/>
<collection name="https://example.com/0" count="1"/>
What I have seen most typically with applications built on MarkLogic is that they either have a single search ui for all document types, or separate search ui for each document type. You can always to full-text search across any document type, and you can define and show facets regardless if they apply to all or only a subset of the documents. Collection name could be a facet for instance, but you could also have a facet called Keyword that only applies to two of the collections, and another facet called Company that applies to three other ones.
In short, think of what end users functionality you'd like to provide first, and think how to technically implement that as second step. I doubt knowing the namespaces truly matters to the search ui, and likely only matters on index level.
HTH!

empty & not empty word constraint search

I created word constraint on element repository
<constraint name="repository">
<word>
<element ns="http://lmpublishlearning.com" name="repository"/>
</word>
</constraint>
we have some document in which element repository value is blank like
<lmp:repository/>
Now in our search application how I can pass above type to get blank value document with word constraint. I try below different case but not able to get result.
rs:q=repository:''&rs:pageLength=10&rs:start=1&rs:sort=relevance"
rs:q=repository:""&rs:pageLength=10&rs:start=1&rs:sort=relevance"
It might meet your requirements to write a custom constraint:
http://docs.marklogic.com/guide/search-dev/search-api#id_97085
that returns
a cts:element-word-query on a tagged value that's not empty
a cts:element-value-query on a tagged value that is empty
Hoping that helps,

Unfiltered Search Option does not return Accurate Results

In Marklogic, I have to do unfiltered search in order to return the results of the facets. But, this option returns inaccurate results that does not have Search highlight.
I used the searchable Expression in order to get the Path of the Search results, here is the options that I used:
<search-option>unfiltered</search-option>
<searchable-expression>
/Book//chapter
</searchable-expression>
<constraint name="chapter">
<word>
<element name="chapter"/>
</word>
</constraint>
<constraint name="Author">
<range type="xs:string" collation="http://marklogic.com/collation/codepoint">
<element name="author"/>
</range>
</constraint> </options>
Also, I tried to add element query constraint, but it affect the performance of the search query
This is the search query:
search:search("chapter:List of Scenes", $options);
(SO timed out) If you're getting no facets with filtered search, it's because the search didn't produce facets. An unfiltered search can produce facets on text that didn't match the search but was in the same document as a matching indexed term.
Unfiltered searches are not a drop-in replacement for Filtered searches. If the Filtered searches are too slow then you should analyze your queries and data to find where optimizations are appropriate. Often a compromise is used - optimize a few searches to be fast, then use the results of those to do a 2nd filtered search on a subset of the results as needed to fill in the detail. See https://docs.marklogic.com/guide/performance.

Using GUID with SQL Server and NHibernate

I'm running NHibernate and SQL Server CE I am trying to use GUIDs as my ID column. This is the code I already have:
Mapping:
<class name="DatabaseType" table="DBMON_DATABASE_TYPE">
<id name="Id" column="DATABASE_TYPE_ID">
<generator class="guid" />
</id>
<property name="DispName" />
</class>
And this is the create statement it creates:
create table DBMON_DATABASE_TYPE (
DATABASE_TYPE_ID BIGINT not null,
DispName NVARCHAR(255) null,
primary key (DATABASE_TYPE_ID)
)
And this is the kind of insert statement I want to be able to run on it:
Insert into DBMON_DATABASE_TYPE (DATABASE_TYPE_ID,DISPNAME) values ('f5c7181e-e117-4a98-bc06-733638a3a264','DOC')
And this is the error I get when I try that:
Major Error 0x80040E14, Minor Error 26306
> Insert into DBMON_DATABASE_TYPE (DATABASE_TYPE_ID,DISPNAME) values ('f5c7181e-e117-4a98-bc06-733638a3a264','DOC')
Data conversion failed. [ OLE DB status value (if known) = 2 ]
Once again my goal is to be able to use GUIDs as the ID column of my table, they don't even need to be auto generated, I can generate them manually in the Save/SaveOrUpdate methods of NHibernate. If there is any other information you need to know please let me know!
In your mapping you need to identify that you want NHibernate to create a GUID in the database schema (it looks like you are generating your schema from the nhibernate mapping). Off the top of my head the following should work:
<id name="Id" column="DATABASE_TYPE_ID" type="Guid">
<generator class="guid" />
</id>
instead of
DATABASE_TYPE_ID BIGINT not null,
it needs to be
DATABASE_TYPE_ID UNIQUEIDENTIFIER not null,
I would strongly advice you to use NEWSEQUENTIALID() as a default instead since you are using it as a clustered index because it won't cause page splits and thus fragmentation, see here how to use it http://msdn.microsoft.com/en-us/library/ms189786.aspx
Dare I recommend using GuidComb's instead?

Resources