Java 3.0 get distinct values from a column mongodb - java

I am really struggling here and have looked at other questions but just cant seem to get the answer I need.
What I am trying to do is pull through all the unique values of a column and then iterate through them and add them to an array. Ending up with the one column being stored in my array, but one of each value that exists not the multiple like there currently is.
Every time I try and do .distinct it asks me for the return class I have tried many different class but it just doesn't seem to work... Code is below any help would be appreciated.
public static void MediaInteraction() {
//Storing data from MediaInteraction in MediaArray
//BasicDBObject Query = new BasicDBObject();
//Query.put("consumerid", "");
MongoCursor<Document> cursormedia = collectionmedia.distinct("consumerid", (What do I put here?)).iterator();
while (cursormedia.hasNext()) {
System.out.println(cursormedia.next());
MediasessionID.add(cursormedia.next());
}
System.out.println("Media Array Complete");
System.out.println(MediasessionID.size());
}

The change that you probably want to introduce shall be somewhat like -
MongoCursor<Document> cursormedia = collectionmedia.distinct("consumerid",
<ConsumerId-DataType>.class).iterator(); //please replace the consumerId field's datatype here
Also from the docs -
/**
* Gets the distinct values of the specified field name.
*
* #param fieldName the field name
* #param resultClass the class to cast any distinct items into.
* #param <TResult> the target type of the iterable.
* #return an iterable of distinct values
* #mongodb.driver.manual reference/command/distinct/ Distinct
*/
<TResult> DistinctIterable<TResult> distinct(String fieldName, Class<TResult> resultClass);
So in your example, if you are trying to attain cursor for Document you probably want to use Document.class in the above suggested code.
Edit - Also the fact that you are calling cursormedia.next() twice the count of your MediasessionID would be halved. Suggest you do that(.next) once improving it further to obtain results.

Related

Couchbase Lite - use coalesce / ifNullOrMissing in order by clause

I have documents stored in a couchbase lite database. I use the query builder to request these documents in Java.
I would like to to order the retrieved documents given two properties: if one is missing, I'd like to use the value of another for the ordering.
For example, considering these data stored in the couchbase lite:
{
"firstname":"Russell",
"lastname":"Macdonald"
},
{
"firstname":"Brielle"
"birthname":"Vaughn"
"lastname":"Bates"
},
{
"firstname":"Molly"
"birthname":"Arellano"
"lastname":"Nichols"
}
I would like to order by birthname. But if the birthname is missing, the lastname should be used instead. The resulting order would be:
Molly Arellano (married Nichols)
Russell Macdonald
Brielle Vaughn (married Bates)
I tried passing the two successive properties to the order by clause. But, unsurprisingly, it did not work:
List<Result> results = select(all())
.from(database(myDatabase))
.orderBy(Ordering.property("birthname"), Ordering.property("lastname"))
.execute().allResults()
I don't think you can do this with the QueryBuilder interface. SQL+, however, has a function: "IFMISSINGORNULL(arg1, arg2)" whose value is its first argument, if ISMISSINGORNULL is false for that argument and its second argument otherwise. You should be able to use the query:
"select * from _ order by IFMISSINGORNULL(birthname, lastname)"
FWIW, the ResultSet produced by Query.execute() should be closed. It is AutoClosable so you might do something like this:
final Query query = db.createQuery("select * from _ order by IFMISSINGORNULL(birthname, lastname)");
try (ResultSet results = query.execute()) {
// parse the results...
}

Using a Markov Model to analyze a text input in Java

I'm very new to Java and I'm required to use a Markov Model to analyze a text (String) input. I will be honest: this is for an assignment. I am looking to learn how to answer it, not just copy and paste code.
The code I am working with (this is given and cannot be altered) is below:
public class MarkovModel
{
/** Markov model order parameter */
int k;
/** ngram model of order k */
NgramAnalyser ngram;
/** ngram model of order k+1 */
NgramAnalyser n1gram;
/**
* Construct an order-k Markov model from string s
* #param k int order of the Markov model
* #param s String input to be modelled
*/
public MarkovModel(int k, String s)
{
//TODO replace this line with your code
}
the exact question is: Complete the code for the constructor, which takes an integer k, and an input string s, and initializes any data structures needed for a k-th order Markov model.
We are also using an n-gram analyser, and the text should wrap around (for example, with "abbbc", the 3-grams would be abb, bbb, bbc, bca, and cab). Please let me know if you need any more information! Again, I am not looking to copy and paste code, just want a little bit of help understanding how to solve it.
Thanks in advance.

MongoTemplate findAndModify get updated document count

I'm using MongoTemplate to implement a method that can update multiple documents according to the query, and return the updated document count.
When I was using MySQL, update method usually return the updated data count as default, so I'm wondering how can I get the same thing in mongo?
Also, using the findAndModify because I want the function to be multi-thread-safe.
Please help...
findAndModify updates only one document instead in MongoTemplate we have updateMulti which updates multiple document and return a writeResult which can tell you how many documents were updated
/**
* finds the elements based on query and modifies it
*
* #param query
* #param update
* #param clazz
* #return
* #throws MeowException
*/
protected <T> WriteResult modifyAll(final Query query, final Update update, final Class<T> clazz) throws MeowException{
try{
return getMongoTemplate().updateMulti(query, update, clazz);
}catch(Exception ex){
throw new MeowException(ex).withParam("query", query).withParam("update", update).withParam("class", clazz).logToFile("Exception in modifyAll");
}
}
This can be called as
WriteResult result = modifyAll(query, update, Kitten.class);
logger.error("document updated count :"+result.getN());
Hope it helps.

Check whether the document exists using Mongodb and Java?

I have created a simple java application as my college mini project in which one of the module I'm allowing users to perform operations like insert, delete, update and search.
For validation purposes I want a to display an error message to the user if he tries to delete a record which isn't present in the DB like
"Sorry record not found" .
I have tried try catch block to check that if mongodb throws a exception if document not found but that didn't worked. I'm new in Java and Mongodb and need help.
Here's my code of deleteActionPerformed and of what I tried:
private void deleteActionPerformed(java.awt.event.ActionEvent evt) {
try {
// my collection name is activity
DBCollection col = db.getCollection("activity");
// Tid is the TextField in which i am taking input of _id
if(!Tid.getText().equals("")) {
col.remove(new BasicDBObject().append("_id",(Object)Tid.getText()));
} else {
JOptionPane.showMessageDialog(null,"Please Enter the ID");
}
} catch(Exception e){
JOptionPane.showMessageDialog(null,"Record not Found " + e);
}
}
The try catch block is not generating a not found type exception.
This may not by the most efficient method, but it ought to work.
I adapted it from some code of mine looking for a particular document value (other than _id).
There may be a specialized method for _id.
/**
* Checks if an activity exists with a given id. if no such activity exists
* returns false. Returns true for one or more activities with a matching id.
*
* #param db
* #param id
* #return boolean - true if one or more functions with matching names exit.
*/
public static boolean activityExists(MongoDatabase db, ObjectId id) {
FindIterable<Document> iterable = db.getCollection("activity")
.find(new Document("_id", id));
return iterable.first() != null;
}
EDIT: It seems that it is best to use the count method. Please refer to the following answer:
How to check if document exists in collection using mongo Java driver 3.0+
In your case, it is significantly faster to use find() + limit() because findOne() will always read + return the document if it exists. find() just returns a cursor (or not) and only reads the data if you iterate through the cursor.
So instead of:
db.collection.findOne({_id: “myId”}, {_id: 1})
you should use:
db.collection.find({_id: “myId”}, {_id: 1}).limit(1)

Better way to represent array in java properties file

I'm currently making a .properties file that needs to be loaded and transformed into an array. But there is a possibility of anywhere from 0-25 of each of the property keys to exist. I tried a few implementations but i'm just stuck at doing this cleanly. Anyone have any ideas?
foo.1.filename=foo.txt
foo.1.expire=200
foo.2.filename=foo2.txt
foo.2.expire=10
etc more foo's
bar.1.filename=bar.txt
bar.1.expire=100
where I'll assemble the filename/expire pairings into a data object, as part of an array for each parent property element like foo[myobject]
Formatting of the properties file can change, I'm open to ideas.
I can suggest using delimiters and using the
String.split(delimiter)
Example properties file:
MON=0800#Something#Something1, Something2
prop.load(new FileInputStream("\\\\Myseccretnetwork\\Project\\props.properties"));
String[]values = prop.get("MON").toString().split("#");
Hope that helps
Didn't exactly get your intent.
Do check Apache Commons configuration library http://commons.apache.org/configuration/
You can have multiple values against a key as in
key=value1,value2
and you can read this into an array as configuration.getAsStringArray("key")
Either define a delimiter that will not be a potential value or learn to use XML.
If you still insist on using properties use one of the methods that will return a list of all keys. Your key appears to have three parts a group identifier (foo, bar) an index (1, 2) and then an element name (filename, expire). Get all the keys break them into their component parts. Create a List for each type of identifier, when processing the list use the identifier to determine which List to add to. Create you paired elements as you said and simply add to the list! If the index order is important either add that as a field to your paired elements or sort the keys before processing.
Use YAML files for properties, this supports properties as an array.
Quick glance about YAML:
A superset of JSON, it can do everything JSON can + more
Simple to read
Long properties into multiline values
Supports comments
Properties as Array
YAML Validation
I have custom loading. Properties must be defined as:
key.0=value0
key.1=value1
...
Custom loading:
/** Return array from properties file. Array must be defined as "key.0=value0", "key.1=value1", ... */
public List<String> getSystemStringProperties(String key) {
// result list
List<String> result = new LinkedList<>();
// defining variable for assignment in loop condition part
String value;
// next value loading defined in condition part
for(int i = 0; (value = YOUR_PROPERTY_OBJECT.getProperty(key + "." + i)) != null; i++) {
result.add(value);
}
// return
return result;
}
I highly recommend using Apache Commons (http://commons.apache.org/configuration/). It has the ability to use an XML file as a configuration file. Using an XML structure makes it easy to represent arrays as lists of values rather than specially numbered properties.
here is another way to do by implementing yourself the mechanism.
here we consider that the array should start with 0 and would have no hole between indice
/**
* get a string property's value
* #param propKey property key
* #param defaultValue default value if the property is not found
* #return value
*/
public static String getSystemStringProperty(String propKey,
String defaultValue) {
String strProp = System.getProperty(propKey);
if (strProp == null) {
strProp = defaultValue;
}
return strProp;
}
/**
* internal recursive method to get string properties (array)
* #param curResult current result
* #param paramName property key prefix
* #param i current indice
* #return array of property's values
*/
private static List<String> getSystemStringProperties(List<String> curResult, String paramName, int i) {
String paramIValue = getSystemStringProperty(paramName + "." + String.valueOf(i), null);
if (paramIValue == null) {
return curResult;
}
curResult.add(paramIValue);
return getSystemStringProperties(curResult, paramName, i+1);
}
/**
* get the values from a property key prefix
* #param paramName property key prefix
* #return string array of values
*/
public static String[] getSystemStringProperties(
String paramName) {
List<String> stringProperties = getSystemStringProperties(new ArrayList<String>(), paramName, 0);
return stringProperties.toArray(new String[stringProperties.size()]);
}
Here is a way to test :
#Test
public void should_be_able_to_get_array_of_properties() {
System.setProperty("my.parameter.0", "ooO");
System.setProperty("my.parameter.1", "oO");
System.setProperty("my.parameter.2", "boo");
// WHEN
String[] pluginParams = PropertiesHelper.getSystemStringProperties("my.parameter");
// THEN
assertThat(pluginParams).isNotNull();
assertThat(pluginParams).containsExactly("ooO","oO","boo");
System.out.println(pluginParams[0].toString());
}
hope this helps
and all remarks are welcome..
As user 'Skip Head' already pointed out, csv or a any table file format would be a better fitt in your case.
If it is an option for you, maybe this Table implementation might interest you.
I'd suggest having the properties file, reference a CSV file.
Then parse the CSV file into a collection/array etc instead.
Properties file seems wrong fit for this kind of data.
Actually all answers are wrong
Easy: foo.[0]filename

Categories