I'm using the Apache Chemistry OpenCMIS java library. Given a QueryResult (e.g. I found a document or a bunch of documents by searching on metadata properties), is this a reasonable way to retrieve the Document object itself? Or is there a more efficient way?
ItemIterable<QueryResult> results = session.query("SELECT * FROM cmis:document WHERE cmis:name LIKE 'test%'", false);
for(QueryResult hit: results) {
Document document = (Document) session.getObject(session.createObjectId((String) hit.getPropertyValueById("cmis:objectId")));
}
Try the Session.queryObjects() method.
For me this works perfectly
String myType = "my:documentType";
// get the query name of cmis:objectId
ObjectType type = session.getTypeDefinition(myType);
PropertyDefinition<?> objectIdPropDef = type.getPropertyDefinitions().get(PropertyIds.OBJECT_ID);
String objectIdQueryName = objectIdPropDef.getQueryName();
String queryString = "SELECT " + objectIdQueryName + " FROM " + type.getQueryName();
// execute query
ItemIterable<QueryResult> results = session.query(queryString, false);
for (QueryResult qResult : results) {
String objectId = qResult.getPropertyValueByQueryName(objectIdQueryName);
Document doc = (Document) session.getObject(session.createObjectId(objectId));
}
Found here: https://chemistry.apache.org/java/examples/example-process-query-results.html
Related
I am trying to insert the document which is received by input system in mongodb database by using upsert option but it is failing with below error :
Anyone help me how to perform the upsert to avoid the duplicate transactions based on field
**Write error: WriteError{code=61, message='Failed to target upsert by query :: could not extract exact shard key', details={}}.**
#ResponseBody
public boolean createTickets(#Valid #RequestBody Document... service) {
MongoDatabase database = this.mongoClient.getDatabase("database");
MongoCollection<Document> collection = database.getCollection("Test");
List<Document> documentList = new ArrayList<>(bookings.length);
for (Document service : bookings) {
documentList.add(Document.parse(booking.toJson()));
}
Document doc= (Document) documentList.iterator().next().get("Price");
String priceResults = (String) doc.get("Ticket");
UpdateOptions options = new UpdateOptions().upsert(true);
UpdateResult updateResult = collection.updateOne(Filters.eq("Price.Ticket", priceResults),
Updates.combine(Updates.set("Price.Ticket", priceResults)), options);
System.out.println("updateResult:- " + updateResult);
I have list of attributes in mongo and I am querying some nested field. Here is my code,
public List<Brand> searchBrands(Request request) {
final MongoCollection<Document> collection = mongoDatabase.getCollection("shop");
final Document query = new Document();
final Document projection = new Document();
final List<Brand> brandList = new ArrayList<>();
query.append("_id", request.getId());
query.append("isActive", true);
if (request.Year() != null) {
query.append("attributes.name", "myYear");
query.append("attributes.value", request.getYear());
}
projection.append("brand.code", 1.0);
projection.append("brand.description", 1.0);
projection.append("_id", 0.0);
Block<Document> processBlock = document -> brandList.
add(Brand.builder().code(document.get("brand",Document.class).getString("code"))
.description(document.get("brand",Document.class).getString("description"))
.build());
collection.find(query).projection(projection).forEach(processBlock);
return brandList;}
Above code return results correctly, 72 item with same brand.code. But I want to fetch distinct according to brand.code How can I do that?
I'm not sure which mongodb client library you're using to create queries for mongodb;
I'm sharing the query that you can run in mongodb console to get the results you want. I hope you know how to create this query using your mongodb client library
db.shop.distinct('brand.code', myQuery)
//Replace myQuery with your query e.g. {isActive: true}
I am using google.cloud.bigquery library to execute and create query using bigquery.query() method. I want to fetch the Schema details from the response but whenever the query returns no result, I am getting EmptyTableResult instead of the response which should have Schema and Fields listed inside it. I used another approach which creates job and then using the query job, I am calling bigquery.getQueryResults which should return QueryResponse object. Below is the code snippet.
QueryJobConfiguration queryConfig =
QueryJobConfiguration.newBuilder(queryString)
.setDefaultDataset(bqDatasetId).setUseLegacySql(false)
.setFlattenResults(true).build();
JobId jobId = JobId.of(UUID.randomUUID().toString());
Job queryJob = bigQuery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());
// Wait for the query to complete.
queryJob = queryJob.waitFor();
// Check for errors
if (queryJob == null) {
throw new RuntimeException("Job no longer exists");
} else if (queryJob.getStatus().getError() != null) {
throw new RuntimeException(queryJob.getStatus().getError().toString());
}
// Get the results.
QueryResponse response = bigQuery.getQueryResults(queryJob.getJobId());
System.out.println(response);
Here, in sysout statement, I am getting the proper response, but whenever I am trying to use response.getSchema(), it is giving me compilation error saying getSchema() is not visible. Can anyone help me with this? Is this approach correct or there is any other approach which can do the same thing?
You need to call getQueryResults() on the Job object instead. This will give you back a TableResult object. You can then call getSchema() to get the schema of the query/table/job. So, putting it all together:
QueryJobConfiguration queryConfig =
QueryJobConfiguration.newBuilder(
"SELECT "
+ "CONCAT('https://stackoverflow.com/questions/', CAST(id as STRING)) as url, "
+ "view_count "
+ "FROM `bigquery-public-data.stackoverflow.posts_questions` "
+ "WHERE tags like '%google-bigquery%' "
+ "ORDER BY favorite_count DESC LIMIT 10")
.setUseLegacySql(false)
.build();
JobId jobId = JobId.of(UUID.randomUUID().toString());
Job queryJob = BIGQUERY.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());
queryJob = queryJob.waitFor();
TableResult result = queryJob.getQueryResults(); //<--you need this
Schema schema = result.getSchema(); //<--..and this
System.out.println(schema);
Which yields:
Connected to the target VM, address: '127.0.0.1:64695', transport: 'socket'
Schema{fields=[Field{name=url, type=STRING, mode=NULLABLE, description=null}, Field{name=view_count, type=INTEGER, mode=NULLABLE, description=null}]}
After searching a lot, I came to a conclusion that it is better to use reflections to invoke the invisible QueryRespons.getSchema() method and it worked like a charm. Though, reflection is not an ideal solution for this but it has resolved my problem.
public static JSONArray convert(TableResult resultSet) throws Exception {
JSONArray jsonArray = new JSONArray();
Schema schema = resultSet.getSchema();
FieldList MyFields = schema.getFields();
Field MyField2 = null;
for (FieldValueList row : resultSet.iterateAll()) {
JSONObject obj = new JSONObject();
for (int i = 0; i < MyFields.size(); i++) {
MyField2 = MyFields.get(i);
obj.put(MyField2.getName().toLowerCase(), row.get(i).getValue());
}
jsonArray.put(obj);
}
return jsonArray;
}
Another approach is to use the solution in this ticket Querying Column Headers in GBQ
This is running a query and not using the api
I have the following json structure. I am trying to retreive run the following mongo query in java where hData._id is not null.
MongoDb Query: db.Collection.find({},{"hData._id":1, "hData.createdBy":1} )
{
"_id" : ObjectId("55567e594e3256a23565ce58"),
"hData" : {
"isDeleted" : false,
"canDelete" : false,
"canUpdate" : false,
"createdBy" : “xyz”,
"createdDate" : "2015-05-15T15:05:30",
"_id" : "7"
},
"changeDate" : "2015-02-19T16:02:12",
}
The code i have written in java to fetch the hData._id is
MongoCursor<Document> cur = col.find(new BasicDBObject("hData._id", new BasicDBObject("$ne",null)))).iterator();
try{
while(cur.hasNext()){
System.out.println(cur.next().getObjectId("hData._id"));
i++;
}
}finally {
cur.close();
}
However, hData._id is returned as null. Could you help me with this ?
You can't get nested properties using dot notation, e.g. x.y.
So in your example you need to get hData first, then call get on the _id. Like this:
MongoCursor<Document> cur = col.find(new BasicDBObject("hData._id", new BasicDBObject("$ne",null))).iterator();
while(cur.hasNext()){
System.out.println(cur.next().get("hData", Document.class).getString("_id"));
}
Also note that in your example hData._id is shown as a String and not as an ObjectId, hence in my example I've used getString().
EDIT
Since it sounds like you may have mixed types for hData._id here's a more robust example with type checking and some extra debug output to illustrate:
MongoCursor<Document> cur = col.find(new BasicDBObject("hData._id", new BasicDBObject("$ne",null))).iterator();
while(cur.hasNext()){
Document doc = cur.next();
System.out.println("Document _id" + doc.get("_id"));
Document hdata = doc.get("hData", Document.class);
Object id = hdata.get("_id");
System.out.println("hData._id " + id);
// check type if you need to
if (id instanceof String) {
System.out.println("hData._id is String: " + id);
} else if (id instanceof ObjectId) {
System.out.println("hData._id is ObjectId: " + id);
} else {
System.out.println("hData._id is of type " + id.getClass().getName());
}
}
You can use Filters and Projections helper methods.
try (MongoCursor<Document> cur = coll.find(Filters.ne("hData._id", null)).projection(Projections.include("hData._id", "hData.createdBy")).iterator()) {
while(cur.hasNext()){
Document doc = cur.next();
Document hData = doc.get("hData", Document.class);
String id = hData.getString("_id");
String createdBy = hData.getString("createdBy");
}
}
I am trying to use a JEST Client to search the remotely located ElasticSearch index.
However I've ran into a problem - every single query, be it constructed using various builders or just default ES queries, everything returns
com.google.gson.stream.MalformedJsonException
Code:
String URL = "http://api.exiletools.com:80";
String API_KEY = "DEVELOPMENT-Indexer";
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(new HttpClientConfig.Builder(URL)
.defaultCredentials("apikey", API_KEY)
.build());
JestClient client = factory.getObject();
qb = QueryBuilders
.boolQuery()
.must(QueryBuilders.termQuery("attributes.league", "Standard"))
.must(new TermQueryBuilder("attributes.equipType", "Ring"))
.must(new TermQueryBuilder("shop.verified", "yes"));
searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(qb);
query = searchSourceBuilder.toString();
search = new Search.Builder(query).build();
client.execute(search); // Here I get the error
As a final test I just copied the smallest query I could find from Jest integration test examples and just replaced the search terms there, to look like:
query = "{\n"
+ " \"query\" : {\n"
+ " \"term\" : { \"shop.chaosEquiv\" : \"167\" }\n"
+ " }\n"
+ "}";
This query when copied from the output stream looks like this:
{
"query" : {
"term" : { "shop.chaosEquiv" : "167" }
}
}
No trailing whitespaces or anything, looks valid to me.
Still getting the same error.
Can anyone tell what is going on?