Search and retrieve from multiple Collection in MarkLogic? - xquery

How can I fix the following code, if I would like to
specify multiple collections? (like 'pdf' AND 'systemA')
for $doc in fn:collection("pdf")

If you want to get documents that are in either the "A" or "B" collections. in MarkLogic you can pass multiple URIs: fn:collection(("A","B")). If you want documents that are in both the "A" and "B" collections simultaneously, you'll either have to do this as a search
cts:search(doc(),
cts:and-query((cts:collection-query("A"),cts:collection-query("B")),"unfiltered")
or do the set intersection manually
let $as := fn:collection("A")
return fn:collection("B")[not(. is $as)]
The search would be more efficient, since it can use indexes to resolve.

Related

firebase query - find doc where map value is in an array

I'm trying to find the id of a doc where a map value in an array of maps equals "x".
in the following case, I'm trying to find which rep owns the cause with code "hog"
I'll likely be going down the denormalizing route, but is this possible?
Firestore has an array-contains operator that you can use to query whether a certain item exists in an array field, but that operator only works if you specify the exact, complete value of the field. It can't test for a partial match.
The common approach to your use-case is to add an additional array field with just the values you want to query on, i.e.
cause-codes: ["hog"]
Once you modified your documents with this additional field, you can then use a query like:
repsRef.where('cause-codes:', 'array-contains', 'hof')

How to match a list with my firebase documents list out of order?

if I want to find a document in a collection where my list is equal to that of the document I would do so like;
FirebaseFirestore.instance.collection("movies/collection/").where("my_list", isEqualTo: movie_list).limit(1).get();
but in this way the ordering of my_list and movie_list matters and has to match exactly.. I need some way of checking that the two list have the exact same movies in them, regardless of the ordering
There is no array-contains-all operator and hence you cannot check if more than one items exists in an array. Even if you have all the elements of the array they must be in same order. If you could make sure the order is always alphabetical (or any particular pattern) that may work out.
However, I'd recommend converting that to a map which will be easier to query. So instead of ["one", "two"], a map like {"one": true, "two": true} can be queried by chaining multiple .where("myMap.one", isEqualTo: true) clauses.

Firestore Security Rule limit field entry

In my Firestore document, I am trying to limit the fields that the users could update to only the ones I allow. I thought about a function that could check if request.resource.keys() contains any keys that are not the ones I allow, if it does, I block update, if not, I allow update. so far, my function looks like this:
function field_limit() {
let allow_keys = ["field1", "field2", "field3"];
return request.resource.keys() in allow_keys;
}
inside the path match:
allow update: if field_limit();
When I run a unit test in Emulator that modifies "field1", it does not pass. I think I am doing something wrong here because I am comparing the whole keys list against the allow_keys list.
What should I do in order to achieve the desired functionality then?
I thought about a solution to iterate through request.resource.keys(), and see if each key is in allow_keys. If one isn't, block update. But how to traverse through each value of a list?
edit. Should be request.resource.data.keys() instead of request.resource.keys(). Otherwise, it won't work.
The in operator doesn't work the way you're expecting. See the documentation for that - it only checks if a single value is in a list.
If you want to check if a list of values contains only a subset of values in another list, you should use hasOnly instead.
request.resource.keys().hasOnly(allow_keys)
This will evaluate true if the list request.resource.keys() contains only values from the allow_keys list.

How to query mongodb collection field names from R mongolite package

I would like to return the field names of a given mongodb collection from R mongolite.
Starting from mongolite recent versions (i.e 1.5+), you can run a raw command on the mongodb, I can use the below for instance to return all the collections:
m = mongo(db = 'dbname', url='urlofdb')
m$run('{"listCollections":1}')
This would return a list of collection:
$cursor
$cursor$id
[1] 0
$cursor$ns
[1] "db.$cmd.listCollections"
$cursor$firstBatch
name type readOnly idIndex.v idIndex._id idIndex.name idIndex.ns
1 collection-name collection FALSE 1 1 _id_ db.collection
Can you please advise how I could return the column names of a given collection using the run command?
Thanks!
I don't think you really can do it directly.
If you could, that would largely go against the entire philosophy of a NoSQL-database (which Mongo is). The idea behind a NoSQL-database is that you have a collection of documents, which can all have their own fields.
The analogy to paper documents really does work, and the concept of 'columns' is replaced by 'fields', which don't pertain to the collection as a whole, but to individual documents, and each document can contain anything. And there is no overarching mandatory template into which everything must fit. In practice, a lot of documents will have a similar structure, but this is by no means guaranteed. This means that it's entirely possible that you have 100 million documents with 3 fields called "a", "b" and "c", and that document 100000001 has 4 fields: a, b, c and d.
It could be that the database-engine keeps track of what fields are somewhere in a collection, but I doubt that. And if it doesn't, the only way to get all four names a, b, c and d, is to go through all 100000001 documents (or more), which will take a while. Undoubtedly, some optimisation is implemented, but it will always be a hard question.
If you just want an answer for a small DB, I think simply querying for all documents and taking the column-names of the resulting data.frame is easiest.
But if your database is large, this question is no longer about R or mongolite, and I'm not sufficient enough in working with Mongo to help you further.

what happens if i don't specify the collection name in Corb

I have a corb script to run node replace on the xml files.
If I don't specify the collection, will it remove the documents from the existing collections?
If you are altering the document with xdmp:node-replace(), then the document will remain in it's collections and you do not need to worry about setting/adding it back.
If you are using xdmp:document-insert() to replace the document at the current URI, then you do need to specify the collection(s), otherwise it will be removed from the existing collections.
However, you can use xdmp:document-get-collections() to retrieve the sequence of collections for the URI and use it for the 4th parameter of xdmp:document-insert()
xdmp:document-insert($URI, $doc, (), xdmp:document-get-collections($URI))
Its better to provide an empty collection value, while doing the node-replace so it doesn't alter the existing collections of the document. Not defining this attribute is throwing errors while running the script.

Resources