MongodDB Java driver v3 - how to create cursor with projection? - mongodb-java

The following works with mongodb java driver v2. How do I achieve the same result with new drivers of v3 using new set of classes like MongoCollection, etc:
QueryBuilder query = QueryBuilder.start().and(...);
DBObject projection = new BasicDBObject();
projection.put("_id", 1);
projection.put("h", 1);
DBCursor cursor = new DBCursor(collection, query.get(), projection);
while(cursor.hasNext()){
DBObject dbo = cursor.next();
String h = dbo.get("h").toString();
...
}
I particularly want to use projection and iterate over large result set. Also, if there is good reference guide about how to migrate from v2 to v3, I'd be very grateful. So far lost in documentations..

For starters, you really shouldn't be creating a DBCursor yourself. You should be getting them via DBCollection. As for the new API version, it'd look something like this:
collection.find(query).projection(new Document(...)))
For more info, see this page.

Related

Is it possible to use ElasticSearch.Net or Nest for dynamic response

Is there a client.Read(...) without generics? I have found none, neither in Nest nor ElasticSearch.Net.
Version 1.5 has an IDocument that might solve my problem but I cannot use that version with Elasticsearch5.5.
All examples, version 5 and 6, of ElasticSearch.Net and Nest require me to know the format of the response as generic at compile time. E.g. Read<Customer>(...)
My problem is that the we do not know the format of the database and we don't know the format of the output; but it should all be configurable.
You can use dynamic as the generic type if the response is truly dynamic.
In 5.x, this will be Json.NET's JObject type under the covers (so you could use JObject instead if you prefer).
In 6.x, dynamic will also work but the actual type will be an internal JObject type. If you would prefer to work with Json.NET's JObject type, you can hook up Json.NET as the serializer using the NEST.JsonNetSerializer nuget package, to use as the serializer for your documents and then use its JObject type as per 5.x.
(Feels strange to answer my own question but I want to show the resulting code for future reference.)
var settings = new ConnectionSettings(new Uri(#"http://localnhost:9200"))
.DefaultIndex("myindex");
var client = new ElasticClient(settings);
var res = client.Search<dynamic>(s => s
.AllTypes());
var rows = res.Documents;
Assert.IsTrue(rows.Count >= 1);
dynamic row = res.Documents.First();
Assert.AreEqual("50.7031526", row.POSITION.lat.ToString()); // It is case sensitive.
Assert.AreEqual(50.7031526, (double)row.POSITION.lat); // Convert to type explicitly.

Only return specific fields in elastic search native query Java api

I'm building a native query but I only want to return certain fields, all of which are held within a parent field. I think I am looking for the QueryBuilders or NativeSearchQueryBuilder equivalent of the REST API's _source. Here's a code example:
NativeSearchQueryBuilder sb = new NativeSearchQueryBuilder()
.withIndices("myIndex")
.withTypes("myType")
.withQuery(QueryBuilders.queryStringQuery("parent.field2:Foo*"));
.withFields("parent.field1");
I'd expect this to return a list of only parent.field1 that are associated with objects that have parent.field2 like Foo*. But it returns nothing.
Thanks for any help!
After some research, I found the answer is in NativeSearchQueryBuilder. I was just using an older version of spring-data elastic search, so I could not see this method: withSourceFilter. The way to do this is:
NativeSearchQueryBuilder sb = new NativeSearchQueryBuilder()
.withIndices("myIndex")
.withTypes("myType")
.withQuery(QueryBuilders.queryStringQuery("parent.field2:Foo*"));
.withSourceFilter(new FetchSourceFilter(<String array of includes>, null));
FetchSourceFilter takes 2 arguments, a String[] array of includes and one of excludes. In my example, I'd have an array like new String[]{"parent.field1"} passed to FetchSourceFilter, which in turn is passed to withSourceFilter. The search above will then return (once built and ran) a list of parent.field1 with parent.field2 like Foo*.
The version I upgraded to was spring-data-elasticsearch 2.0.2.

How to use an api function that wants a value key pair in powershell

I am trying to make an install script with powershell using the microsoft build api. I know how I can do what I want in C#, I have tested a little example, and almost got it ready in powershell. I only need to know what to fill in as key value pair.
C#:
ProjectItemGroupElement slItemGroup = project.Xml.CreateItemGroupElement();
project.Xml.InsertAfterChild(slItemGroup, project.Xml.LastChild);
List<KeyValuePair<string, string>> metadata = new List<KeyValuePair<string, string>>();
var testkvp = new KeyValuePair<string, string>(#"HintPath",#"MyPath");
metadata.Add(testkvp);
slItemGroup.AddItem(#"Reference", #"microsoft.deployment.windowsinstaller", metadata);
In powershell I got as far as this, which works, but I have no idea how to define the third parameter. Can you give me a hint?
$itemGroup = $msBuildProj.Xml.CreateItemGroupElement()
$msBuildProj.Xml.InsertBeforeChild($itemGroup, $myImport)
$itemGroup.AddItem('Reference', 'Microsoft.Deployment.WindowsInstaller')
#$itemGroup.AddItem('Reference', 'Microsoft.Deployment.WindowsInstaller', ???)
I'm pretty sure what you want is a Dictionary object like this:
$metadata = New-Object 'System.Collections.Generic.Dictionary[String, String]'
$metadata.add('HintPath','MyPath')
$itemGroup.AddItem('Reference', 'Microsoft.Deployment.WindowsInstaller', $metadata)
That creates the dictionary, adds the key/value pair, and then uses it to create the item.

FOSElasticaBundle order query

I am integrating FOSElasticaBundle in my Symfony 2.3 project and I need to sort the results by their price property.
Here is my code:
$finder = $this->container->get('fos_elastica.finder.website.product');
$fieldTerms = new \Elastica\Query\Terms();
$fieldTerms->setTerms('taxon_ids', $taxon_ids_array);
$boolQuery->addMust($fieldTerms);
$resultSet = $finder->find($boolQuery);
How I can do this?
Thanks
Try create a \Elastica\Query object which also contains the sorting information, then send this to the finder:
$finder = $this->container->get('fos_elastica.finder.website.product');
$fieldTerms = new \Elastica\Query\Terms();
$fieldTerms->setTerms('taxon_ids', $taxon_ids_array);
$boolQuery->addMust($fieldTerms);
$finalQuery = new \Elastica\Query($boolQuery);
$finalQuery->setSort(array('price' => array('order' => 'asc')));
$resultSet = $finder->find($finalQuery);
Have a look at the elasticsearch docs on the sort parameter to see how to use it properly.
NOTE: \Elastica\Query is quite different to \Elastica\Query\AbstractQuery, the first encapsulates everything you could send to the _search API endpoint (facets, sorting, explain, etc...) The AbstractQuery represents a base type for each of the individual query types (range, fuzzy, terms, etc...).

Chaining queries in Play! Framework

is there a way to chain queries in the "Play!" framework instead of manually writing a query ?
Something like:
Model m = Model.where("name","Bill").where("gender","m").first();
I wonder because I recently switched from Codeigniter + dmz to grails then now to "Play!" and have been a bit disappointed by the queries chaining compared to the framework mentioned above
PS: I'm obviously not talking about the fetch() and the from() methods.
There is a JpqlSelect object with wich you can do
public static Model findBill() {
JpqlSelect select = new JpqlSelect().from("Model").where("name=?").param("Bill").andWhere("gender=?").param("m");
return find(select.toString(), select.getParams().toArray()).first();
}
This helper is far from being complete but it may suits your needs
You can do it with java.persistence Criteria API like that:
CriteriaQuery q = JPA.em().getCriteriaBuilder().createQuery(Model.class)
q.where(<Expression>).where(<Expression>);
TypedQuery<Model> tq = JPA.em().createQuery(q);
List<Model> result = tq.getResultList();
Look here and here for start
An other option could be using http://www.querydsl.com/ with it's jpa integration.

Resources