MongoDB: How to measure latency or other parameters of DB - java

Situation: App has an API part and one of the API calls returns status of MongoDB. Right now it returns only "OK" or "DOWN".
final DB defaultDb = dbFactory.getDb(dbName);
Getting general status of DB from DB object is not a problem. But how I can get some more information? Like latency or other DB parameters? And is it possible to get more?

Take a look at the diagnostic commands in the reference: http://docs.mongodb.org/manual/reference/command/nav-diagnostic/
You can run any of those using DB.command(String) method.
EDIT: I have also found a CommandResult DB.getStats() method in the Java API.

You can use the ELK stack. For e.g., look here:
https://logz.io/blog/mongodb-performance-monitoring-elk-stack/

Related

Internal Server Error due to long XQuery duration (MarkLogic)

I have am currently running through some queries using the Java API provided by MarkLogic. I have installed it through adding the required dependencies to my library. The connection is set up using
DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8000, secContext, ConnectionType.DIRECT);
From here some XQueries are ran using the code shown below
ServerEvaluationCall evl = client.newServerEval().xquery(query);
EvalResultIterator evr = evl.eval();
while(evr.hasNext()){
//Do something with the results
}
However, certain queries takes a long time to process causing an internal error.So Other then reducing the query time required, I am wondering if there is there a way to overcome this? Such as increasing of connection time limit for instance.
====Update===
Query used
xquery version "1.0-ml";
let $query-opts := /comments[fn:matches(text,".*generation.*")]
return(
$query-opts, fn:count($query-opts), xdmp:elapsed-time()
)
I know the regular expression used can be easily replaced by word-query. But for this instance I would like to just used regular expression for searching.
Example Data
<comments>
<date_commented>1998-01-14T04:32:30</date_commented>
<text>iCloud sync settings are not supposed to change after an iOS update. In the case of iOS 10.3 this was due to a bug.</text>
<uri>/comment/000000001415898</uri>
</comments>
On the basis of your provided data I'd use xdmp:estimate and a cts query.
xdmp:estimate(cts:search(doc(), cts:and-query((
cts:directory-query('/comment/'),
cts:element-word-query(xs:QName("text"), "generation")
))))
This will search all documents in your /comments/ directory for an element text containing the word generation. As you already know, this will only use indexes and does not require loading/parsing documents.
This also will not find any false-positives because there is only one text element per document/fragment (if your shown data is correct).

how to make the latest MyBatis Dynamic SQL support pagination for mysql (limit/offset)?

There are some samples on http://www.mybatis.org/mybatis-dynamic-sql/docs/select.html.
I want to implement limit/offset for mysql but failed to see any document on describing how to extend this library to support additional where condition.
here is what i'd like to achieve:
SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight)
.from(animalData)
.where(id, isIn(1, 5, 7))
.and(bodyWeight, isBetween(1.0).and(3.0))
.orderBy(id.descending(), bodyWeight)
.limit(1).offset(10)
.build()
.render(RenderingStrategy.MYBATIS3);
There are a couple of resources you can use.
This page - http://www.mybatis.org/mybatis-dynamic-sql/docs/whereClauses.html - shows an example of using standalone where clauses to build a paging query. This is not exactly what you are looking for, but it shows one way to do it.
There is a unit test showing something that is closer to what you are looking for here - https://github.com/mybatis/mybatis-dynamic-sql/tree/master/src/test/java/examples/paging. This code works for MySQL and you could use it as is.
I hope to make this a little easier in a future release.

WebSocketGremlinRequestEncoder must produce at least one message - janusgraph-dynamodb using withRemote "sideEffect" doesn't work

When I use gremlin-server connection using gremlin-driver in Java, I am not able to use "sideEffect" of GraphTraversal.
graph = EmptyGraph.instance()
cluster = Cluster.open("conf/remote-objects.yaml");
graphTraversalSource = graph.traversal().withRemote(DriverRemoteConnection.using(cluster));
My query that uses sideEffect looks like:
AtomicLong level1 = new AtomicLong(0);
graphTraversalSource.V().hasLabel("user")
.has("uuid", "1234")
.sideEffect(it -> it.get().property("level", level1.getAndIncrement())).emit().repeat(in())
.until(loops().is(5)).valueMap("uuid", "name", "level");
This query used to work when I was using janusgraph-dynamodb-storage-backend as dependency and running gremlin server within Java application and connecting to dyamodb. When i switched to using remote connection to gremlin server running in EC2, i started getting below error message:
java.util.concurrent.CompletionException: io.netty.handler.codec.EncoderException: WebSocketGremlinRequestEncoder must produce at least one message., took 3.895 sec
If I remove the sideEffect part from the above query, it works fine. I really need to add a custom property during traversal and include that in results without saving it in the database.
You have a few problems. The first problem is that you are trying to remote a lambda in the sideEffect() Lambdas can't be serialized to Gremlin bytecode - at least not in the form you've provided. However, you can do this:
gremlin> cluster = Cluster.open("conf/remote-objects.yaml")
==>localhost/127.0.0.1:8182
gremlin> g = graph.traversal().withRemote(DriverRemoteConnection.using(cluster))
==>graphtraversalsource[emptygraph[empty], standard]
gremlin> g.addV('person').as('p').addE('link').to('p')
==>e[1][0-link->0]
gremlin> g.V().sideEffect(Lambda.function("it.get().property('level',1)")).valueMap()
==>[level:[1]]
Note that I had to import import org.apache.tinkerpop.gremlin.util.function.* to the console to make that last line work there - That will be fixed for 3.2.7/3.3.0.
So, you could pass your lambda that way, but:
I don't think your traversal will work as before because you are referencing a variable local to the client with level1 - the server is not going to know anything about that.
TinkerPop generally recommends that you avoid lambdas.
I don't quite follow what your Gremlin is doing to provide a suggestion on how to resolve this. You do give this hint:
I really need to add a custom property during traversal and include that in results without saving it in the database.
...but the Gremlin above does write the value of level1 to the database so I'm not sure of what you are after.

Couchbase Java API not returning values for set range

I'm having a weird problem with Couchbase Java API. I use the following code:
ViewQuery query = ViewQuery.from(BUCKET_NAME, GET_ENTITIES_VIEW_NAME);
...
// set companyStart, companyEnd as Strings
// set query.limit and query.skip
...
query.startKey(toJsonArray(companyStart, Long.toString(params.getStartDate().getTime())));
endKey(toJsonArray(companyEnd, Long.toString(params.getEndDate().getTime())));
ViewResult results;
results = bucket.query(query);
...
When I try the said start and endKeys (like ["ROTOR", 146538100000]) in the Couchbase console, the query returns all the expected results.
However, with the Java API the results is empty.
If I comment out the query.startKey and .endKey lines, it faithfully returns all the results for the view.
Here's my view:
function (doc, meta) {
if(doc.collectorData.documenttypes.terms[0] && doc.collectorData.documenttypes.terms[0]=='EAP:Article') {
emit([doc.collectorData.userdata.company,doc.timestamp], {"visitId":doc.visitId,"visitorId":doc.visitorId,"company":doc.collectorData.userdata.company,"timestamp":doc.timestamp, "userAgent":doc.userAgent, "pathInfo":doc.pathInfo, "channel":doc.collectorData.channel, "newVisit":doc.newVisit});
}
}
Any tips on what may be wrong?
You are using Long.toString, so it is not equivalent to what you used in the couchbase console.
That would be equivalent to ["ROTOR", "146538100000"]. A subtle but meaningful difference!
Try with the following snippet instead (I explicitly used JsonArray.from as well, just to remove any ambiguity):
query
.startKey(JsonArray.from(companyStart, params.getStartDate().getTime()))
.endKey(JsonArray.from(companyEnd, params.getEndDate().getTime()));
Simon's tips were most helpful. The mystery had a simple solution: I forgot to publish the view, and the old view only had one-field key, so the query was executing successfully yet returning nothing! A comment somewhere through the thread on https://forums.couchbase.com/t/not-able-to-get-all-rows-returned-from-couchbase-view/5020/23 provided the enlightenment.

How to call solr analysis api in java?

Is there a way to call solrs analysis api in java using solr-core and get the analyzed tokens.
Analysis api takes fieldName or fieldType and values and give the analyzed tokens.
Is there a way to get those tokens from java?
I found the following link: FieldAnalysisRequestHandler, But I could not get any examples to use it.
In the Admin UI (for which the FieldAnalysisRequestHandler is meant) you can call it by selecting a core and then go to the "Analysis" entry.
See https://cwiki.apache.org/confluence/x/UYDxAQ or https://cwiki.apache.org/confluence/x/FoDxAQ for that.
From a client (which I guess you mean, as you tagged this question with solrj) you need to call the correct URL.
Typically the FieldAnalysisRequestHandler is bound to /analysis/field, see your solrconfig.xml.
From Solrj it should work like this:
SolrQuery query = new SolrQuery();
solrQuery.setRequestHandler("/analysis/field");
solrQuery.set("analysis.fieldtype", "mytype");
solrQuery.set("analysis.fieldvalue", "myval");
QueryResponse solrResponse = solrServer.query(solrQuery);
But it doesn't seem like there's a great support for this in Solrj, probably because it's meant to be called from the Solr Admin UI as mentioned.

Categories