So, I need to sort my collection on MongoDB by fields that are on an array of objects.
I have
"columns": [{
"kind": "FirstKind",
"descriptor": "Description1",
"data": "Data to be sorted"
},{
"kind": "SecondKind",
"descriptor": "Description2",
"data": "Data to be sorted"
}]
What I want to achieve is selecting "FirstKind" and "Description1" or "SecondKind" and "Description2" and sort the collection by the field data. I found a solution to do that on MongoDB, by doing:
db.getCollection('results').aggregate(
[{
"$match": {
"$and": [{
"columns.kind": "FirstKind"
}, {
"columns.descriptor": "Name"
}]
}
},{
"$sort": {
"columns.data": -1
}
},{
"$limit": 20
}]
)
My problem now is how to translate that to ReactiveMongo on Scala. I've been trying to understand this documentation: http://reactivemongo.org/releases/0.11/documentation/advanced-topics/aggregation.html but I'm really confused about it. Has anyone ever used aggregate with ReactiveMongo on Scala? Thanks!
I agree, it is not the most straightforward thing in ReactiveMongo.
I have tried to translate your code into the ReactiveMongo aggregation query syntaxt below. However I haven't run it so you might need to tweak it a little.
val dao = reactiveMongoApi.db.collection[BSONCollection]("results")
import dao.BatchCommands.AggregationFramework._
dao.aggregate(
Match(BSONDocument(
"columns.kind" -> "FirstKind",
"columns.descriptor" -> "Name")),
List(
Sort(Descending("limit")),
Limit(20)))
Related
I am trying to look for a query to update a record in Mongo document using Redash. I came up with the following query but it does not work. Can anyone please help? What I know about Redash is that it uses Pymongo.
{
"collection": "Application",
"update": [{
"$match": {
"ID": "2001"
},
"$set": {
"ID": "2020"
}
}]
}
Never used Redash, but in pymongo the construct would be:
db = MongoClient()['mydatabase'] # Set the database connection
db.Application.update_one({"ID": "2001"}, {"$set": {"ID": "2020"}}) # Perform the update
I have below document in Mongo DB and I wrote a java code to get data from innermost element . For some reason its not returning me any results for it.
Input data
{
"_id": "59036b0fa036cc28c8e07db6",
"srcName":"test1",
"sections": [{
"_id": "8769669696",
"data": [{
"srcKey": "Bonds",
"rowIdx": 0,
"values": [{
"srcDesc": "Assets",
"valuesNumber": 10000
},
{
"srcDesc": "NonAssets",
"valuesNumber": 75500
},
{
"srcDesc": "liabilities",
"valuesNumber": 1566
}
]
},
{
"srcKey": "01",
"rowIdx": 1,
"values": [{
"srcDesc": "NonAssets",
"valuesNumber": 1566
}]
}
]
}]
}
The result I want is
select valuesNumber from...where srcName="test1" AND srcKey="Bonds" AND srcDesc="Assets"
Java code is as below
AggregationOperation match=Aggregation.match(Criteria.where("srcName").in("test1")
.and("sections.data.values.srcDesc").in("Assets")
.and("sections.data.srcKey").in("Bonds"));
AggregationOperation unwind1=Aggregation.unwind("sections");
AggregationOperation unwind2=Aggregation.unwind("sections.data");
AggregationOperation unwind3=Aggregation.unwind("sections.data.values");
Aggregation aggregation=Aggregation.newAggregation(match,unwind1,unwind2,unwind3,match);
BasicDBObject basicDBObject=mongoTemplate.aggregate(aggregation,"InsStatData",BasicDBObject.class).getUniqueMappedResult();
It resolved my question. I just had to do a proper mapping to get Mapped results. that was not there in original code. – user3516787 just now edit
We have a mongodb document as given below, and we configured text index on messageTopic, messageTopicQuestion and answer fields, if i search with a text string then I expect only matched embedded records in the results not the entire document.
For example in below document if i search with word "private", then results should only return the first embedded document not both the records. How to retrieve only matched embedded documents and exclude unmatched ones.
{
"_id": ObjectId("586e8efdde81e56032000084"),
"messageTopic": "My Private",
"messageText": [{
"messageTopicQuestion": "agent private",
"answer": "agent private",
"_id": ObjectId("586e8efdde81e56032000085"),
"keywords": ["private"]
}, {
"messageTopicQuestion": "Greetings Checking",
"answer": "Heloo I am good What about u",
"_id": ObjectId("586fc80ccced739407000f4e"),
"keywords": ["Hi-Good", "Heloo"]
}],
"__v": 3
}
I am using below script
db.getCollection('messagetemplates').aggregate([{
$match: {
$text: {$search: 'private'},
visible: 'PUB'
}
},{ $sort: { score: { $meta: "textScore" } } }])
Appreciate help. Thanks.
I believe the question is a variation of this problem How to get a specific embedded document inside a MongoDB collection?
The issue is how to get the single embedded document and exclude the rest. My suggestion is to use db.collection.find() instead of aggregation.
Something in that sense
db.collection.find({ 'messageText.keyword': 'private' }, {'messageText.$': 1});
, as indicated by the answer above.
messageText.keyword can be replaced with whichever field you want to be searched.
I can confirm that the scenario works on my database.
I'm trying to optimize a mongodb query. I have an index on from_account_id, to_account_id, and created_at. But the following query does a full collection scan.
{
"ts": {
"$date": "2012-03-18T20:29:27.038Z"
},
"op": "query",
"ns": "heroku_app2281692.transactions",
"query": {
"$query": {
"$or": [
{
"from_account_id": {
"$oid": "4f55968921fcaf0001000005"
}
},
{
"to_account_id": {
"$oid": "4f55968921fcaf0001000005"
}
}
]
},
"$orderby": {
"created_at": -1
}
},
"ntoreturn": 25,
"nscanned": 2643718,
"responseLength": 20,
"millis": 10499,
"client": "10.64.141.77",
"user": "heroku_app2281692"
}
If I don't do the or, and only query from_account_id or to_account_id with an order on it, it's fast.
What's the best way to get the desired effect? Should I be keeping account_ids (both from and to) in one field like an array? Or perhaps there is a better way. Thanks!
Unfortunately, as you have discovered, an $or clause can make life difficult for the optimizer.
So, to work around this you have a couple options. Among them:
Divide your query into two and manually merge the results.
Change your data model to allow efficient querying. For example, you might add a "referenced_accounts" field that is an array of all the accounts referenced in the transaction.
I'm relatively new to MongoDB and having trouble with a more advanced upsert. I've been Googling and reading the documentation but having trouble knowing exactly what I'm looking for. Basically I'm creating a hit counter which will store data for multiple domains.
My document structure is:
{
"domain": "example.com",
"hitCount": 1,
"urls": [
{
"url": "/the-url",
"hitCount": 1,
"hits": [
{
"date": "2011-10-30T04:50:01.090Z",
"IP": "123.123.123.123"
}
]
}
]
}
My upsert code so far is:
{
$set: {"domain": "example.com"},
$inc: {"hitCount": 1},
$addToSet: {"urls": {"url": "/the-url"} }
}
This bits working great but as you can see its only the first part of the upsert. I'm having trouble inserting the rest of the data inside "urls" such as incrementing the "hitCount" and adding the "date" and "IP" of the hit.
I was wondering if this document structure is possible in one upsert? I'm starting to think I need to do multiple queries to achieve this?
You must perform multiple queries.