I am using fn:distinct-values but I have faced case sensitive problems.
I need to remove the duplicate values in MarkLogic db.
Result :
Antony
antony
but I want to one result without any duplicate either:
Antony or antony.
If this is just a small set of values, you don't have to create a lexicon for this: distinct-values also takes a collation parameter:
distinct-values(("anthony","Anthony"),"http://marklogic.com/collation//S1")
It's all about collations.
I would suggest that you add a lexicon to whatever attribute or element or property you are referring to. When you set up the lexicon, you can then define the collation to take care of this. In the end, no 'distinct values' is needed because the lexicon will already have a distinct list.
You could use 'distinct values' if you were to normalize your content using uppercase or lowercase in a FLWOR statement in your code, but this is much more costly.
For your reference:
https://docs.marklogic.com/guide/search-dev/encodings_collations
https://docs.marklogic.com/guide/search-dev/lexicon
Related
So, I faced an interview recently with a well known company on Marklogic. He has asked me a question which I couldn't answer. There is an XML example data as below shown.
He asked me how can you get only employee id whose zipcode is 12345 and state is california using search? like cts:search
The thing which came into my mind is write XPath like below but since he asked me using search I couldn't answer
let $x :=//employee/officeAddress[zipCode="38023"]/../employeeId/string()
return $x
xml dataset:
<employees>
<employee>
<employeeId>30004</employeeId>
<firstName>crazy</firstName>
<lastName>carol</lastName>
<designation>Director</designation>
<homeAddress>
<address>900 clean ln</address>
<street>quarky st</street>
<city>San Jose</city>
<state>California</state>
<zipCode>22222</zipCode>
</homeAddress>
<officeAddress>
<address>000 washington ave</address>
<street>bonaza st</street>
<city>San Francisco</city>
<state>California</state>
<zipCode>12345</zipCode>
</officeAddress>
<employee>
</employees>
Using XPath is a natural initial thought for many familiar with XML technologies and starting with MarkLogic. It was what I first started to do when I was just starting out.
Some XPath expressions can be optimized by the database and perform fast and efficiently, but there are also others that cannot and may not perform well.
Using cts:search and the built-in query constructs allows for optimized expressions that will leverage indexes, and allows you to further tune by analyzing xdmp:plan, xdmp:query-meters, and xdmp:query-trace.
An equivalent cts:search expression for the XPath, specifying the path to /employees/employee in the first $path parameter and combining cts:element-value-query with cts:and-query in the second $query parameter would be:
cts:search(/employees/employee,
cts:and-query((
cts:element-value-query(xs:QName("zipCode"), "12345"),
cts:element-value-query(xs:QName("state"), "California") )))/employeeId
You could also use a more generic $path to search against all documents and use an xdmp:element-query() to surround the cts:element-value-query criteria to restrict the search to descendants of the employee element and then XPath into the resulting document(s):
cts:search(doc(),
cts:element-query(xs:QName("employee"),
cts:and-query((
cts:element-value-query(xs:QName("zipCode"), "12345"),
cts:element-value-query(xs:QName("state"), "California") ))
)
)/employees/employee/employeeId
xpath I would have tried (not tested):
/employees/employee[officeAddress/zipCode = '38023' and officeAddress/state = 'California']/employeeId/string()
Note that you can use xdmp:plan on xpath too; it's interesting to see how it works vs cts:search.
In general you're better off putting as much into cts:search as possible vs xpath (and I like xpath!).
The question is a little ambiguous. Are there many employees in one document? Or many employees documents? Both?
Also, don't forget to add the appropriate position indexes, or you won't get much unfiltered help. Look at the plan before and after adding the indexes.
See also https://help.marklogic.com/Knowledgebase/Article/View/queries-constrained-to-elements
Using RODBCext (and Teradata) my SQL query often need to be restricted and is done so with a where statement. However, this is not always required and it would be beneficial to not restrict, but I would like to use a single SQL query. (The actual query is more complex and has several instances of what I'm attempting to apply here)
In order to return all rows, using a wildcard seems like the next best option, but nothing appears to work correctly. For example, the sql query is:
SELECT *
FROM MY_DB.MY_TABLE
WHERE PROC_TYPE = ?
The following does work when passing in a string for proc_type:
sqlExecute(connHandle, getSQL(SQL_script_path), proc_type, fetch = TRUE)
In order to essentially bypass this filter, I would like to pass a wildcard so all records are returned.
I've tried proc_type set to '%', '*'. Also escaped both with backslashes and enclosed with double-quotes, but no rows are ever returned, nor are any errors produced.
You could use COALESCE to do this:
SELECT *
FROM MY_DB.MY_TABLE
WHERE PROC_TYPE = COALESCE(?, PROC_TYPE);
In the event that your parameter is NULL it will choose PROC_TYPE to compare to PROC_TYPE which will return everything.
As for your wildcard attempt you would have to switch over to an operator that can use a wildcard. Instead of =, LIKE for instance. I think you would end up with some oddball edge cases though depending on your searchterm and the data in that column, so the COALESCE() option is a better way to go.
I'm using SQL Developer to create oracle tables. I'm trying to create the columns without quotes, but after creating the table, when I see the DDL, all columns and table names are in quotations. I want all the columns to be case-insensitive.
How do I do that? Please advise.
The context here is, I have my code in PHP. I'm migrating my backend from MySQL to Oracle. While using MySQL, I referenced all my table columns in lower case. But it looks like OCI_FETCH_ARRAY returns the data in Uppercase columns.
So do I have to change my PHP code to use Uppercase or is there any other alternative? I have hell lot of code to change!!
Ahh, finally figured this out. Yes I agree, quotations dont always make an object case-sensitive, but my problem was OCI_FETCH_ALL, OCI_FETCH_ARRAY etc retrieved the table columns in Upper case, whereas I wanted them in lower case. The following statement is a workaround for the issue. it converts the columns into lower case.
$data_upper = oci_fetch_assoc($data_res);
$data = array_change_key_case($data_upper, CASE_LOWER);
Thanks!!
Quotation marks don't always make an object case-sensitive. Objects in all upper-case are always case-insensitive, even if they are surrounded by quotation marks.
SQL> create table test1("QUOTES_DONT_DO_ANYTHING_HERE" number);
Table created.
SQL> select quotes_DONT_do_ANYTHING_here from test1;
no rows selected
You normally only see quotation marks because some tools automatically add them to everything.
I can find the list of indexes for a table by using the following:
PRAGMA index_list(myTable);
From the results of this, I can get details about the columns within an index with the following:
PRAGMA index_info(myIndex);
But I cannot seem to find a way to tell the columns sort order. Is there another pragma that I have overlooked that can let me do this?
Note: I know that I can select from SQLITE_MASTER and parse the sort order out of the create statement, but I would prefer to stay out of parsing if possible. However if this is the only solution, then it will have to work.
After a quick grep through the 3.7.13 source code, I don't believe the sort order is exposed by any of the pragmas. The only references to KeyInfo::aSortOrder that I can find are either in the CREATE INDEX code, or in actual database operations like querying or comparing indices with one another.
It doesn't look like it would be a lot of work to add it to the index_info pragma, if doing a custom build of SQLite is an option for you.
In the following piece of code, what is the purpose of the square?
SELECT Value, [Default] AS Selected FROM SKUOptVal WHERE SKUOptID = ?
Cheers.
This code is written for SQLite3.
It's an identifier. It's the same as saying "Default". It's included for compatibility with MS Access. Since Default is a keyword in SQL, it needs to be quoted if used as an identifier, as it is here.
The column is named default, which is the same as an SQL keyword. Thus, the brackets are used to denote we are referring to the column default and not the keyword default.