combine multiple documents in a couchdb view - couchdb

In couchdb, I need to represent some data in the following format, a outer container that references other documents inside an array.
I want to keep these documents separate as I need to manage conflicts on them individually.
{
"_id" : "1"'
"type" : "container",
"items" : [ "1", "2", "3"]
}
{
"_id" : "2",
"value": "a"
"type" : "item"
}
{
"_id" : "3",
"value": "b"
"type" : "item"
}
{
"_id" : "4",
"value": "c"
"type" : "item"
}
I want to output a view of the data in the following format.
{
"_id" : "1"'
"type" : "container",
"items" : [
{
"_id" : "2",
"value": "a"
"type" : "item"
},
{
"_id" : "3",
"value": "b"
"type" : "item"
},
{
"_id" : "4",
"value": "c"
"type" : "item"
}
]
}
Whats the best way to approach this?

You can achieve this using couchdb linked documents
here is how the view will look like
function(doc){
if(doc.items)
doc.items.forEach(function(item){
emit(doc._id,{_id:item});
})
}
now you can query the view with include_docs=true parameter and you should have the desired result.

Related

Finding an object with multiple items in mongoose

I am having certain issue with querying mongodb using mongoose, but unable to find my required output. Below is the data I am looking for the solution.
I am trying to find with two params here one is location and second is type
{
"_id" : ObjectId("5f04dcf8e123292518a863ae"),
"location" : "Australia",
"name" : "June Bill",
"filters" : [
{
"_id" : ObjectId("5f047efe9fc7ad000f44f990"),
"name" : "Q1",
"type" : "Platinum",
"conditions" : [
{
"And" : [
{
"_id" : "objectid",
"field" : "location",
"value" : "Australia",
"operator" : "equal"
},
{
"_id" : "objectid",
"field" : "name",
"value" : "admin",
"operator" : "equal"
}
]
}
]
},
{
"_id" : ObjectId("5f04d51c0ce40120bbb7dc6e"),
"name" : "Q2",
"type" : "Gold",
"conditions" : [
{
"_id" : ObjectId("5f04d51c0ce40120bbb7dc6f"),
"field" : "ocation",
"value" : "Australia",
"operator" : "equal"
},
{
"_id" : ObjectId("5f04d51c0ce40120bbb7dc70"),
"field" : "start_date",
"value" : "2020-06-01T00 3A00",
"operator" : "equal"
},
]
}
],
"__v" : 0
},
{
"_id" : ObjectId("5f04dcf8e123292518a863ae"),
"location" : "Brazil",
"name" : "June Bill",
"filters" : [
{
"_id" : ObjectId("5f047efe9fc7ad000f44f990"),
"name" : "Q1",
"type" : "Silver",
"conditions" : [
{
"And" : [
{
"_id" : "objectid",
"field" : "location",
"value" : "Australia",
"operator" : "equal"
},
{
"_id" : "objectid",
"field" : "name",
"value" : "admin",
"operator" : "equal"
}
]
}
]
},
{
"_id" : ObjectId("5f04d51c0ce40120bbb7dc6e"),
"name" : "Q2",
"type" : "Gold",
"conditions" : [
{
"_id" : ObjectId("5f04d51c0ce40120bbb7dc6f"),
"field" : "location",
"value" : "Australia",
"operator" : "equal"
},
{
"_id" : ObjectId("5f04d51c0ce40120bbb7dc70"),
"field" : "start_date",
"value" : "2020-06-01T00 3A00",
"operator" : "equal"
},
]
}
],
"__v" : 0
}
here I am trying to find with location and in filters with its type
How Can i do this in mongoose?
I tried
Model.find({'location': 'Brazil', 'filters':{ "$in" : ["Silver"]} });
But it didn't work, Can any one help me achieving actual result?
You can use the . to query the embedded filed or if you want to match multiple fields you can use $elemMatch
db.collection.find({
"location": "Brazil",
"filters.type": {
"$in": [
"Silver"
]
}
},
{
"filters.$": 1
})
MongoDB Playground
If you want to filter out the matched result you can use $ operator in projection
Use this way:
db.collection.find({
"location": "Brazil",
"filters.type": "Silver"
})
MongoDb Playground

elastic search query to select most relevant data for given keyword

I have search query to get data from elastic search DB. The query is below
GET /v_entity_master/_search
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "(*gupta*)",
"fields": [
"id","name","mobile"
]
}
},
{
"query_string": {
"query": "*7542*",
"fields": [
"id","name","mobile"
]
}
}
]
}
}
}
This query return
{
"id":34501,
"name": "sree gupta",
"mobile":"98775421
},
{
"id":12302,
"name": "gupta",
"mobile":"98775422
}
But what I required is, the exact match of the given search key word should be in the 1st result
Expected output is ,
{
"id":12302,
"name": "gupta",
"mobile":"98775422
},{
"id":34501,
"name": "sree gupta",
"mobile":"98775421
}
Please share your suggestion and idea to slove this issue. Thanks in advance
So first of all, why would you search for "(gupta)" in the id and mobile (phone?) field? Based on the two results you shared, they are numeric fields so whats your intention with that?
Same issue with the second must-clause. I've never encountered a real name of a human being that includes numeric values...
I also don't get why you use the wildcards in the first must-clause. I assume you want to do a fulltext search. So you can simply use the match query.
Now to your actual question:
I created an index in my test cluster and indexed the two responses you showed as documents. This is the response when I execute your query:
{
...
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 2.0,
"hits" : [
{
"_index" : "gupta",
"_type" : "_doc",
"_id" : "1",
"_score" : 2.0,
"_source" : {
"id" : 12302,
"name" : "gupta",
"mobile" : "98775422"
}
},
{
"_index" : "gupta",
"_type" : "_doc",
"_id" : "2",
"_score" : 2.0,
"_source" : {
"id" : 34501,
"name" : "sree gupta",
"mobile" : "98775421"
}
}
]
}
}
Notice that both documents have the same score. That's because you specified wildcards in your search query.
Now let's modify your query:
GET gupta/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "gupta"
}
},
{
"query_string": {
"query": "*7542*",
"fields": ["mobile"]
}
}
]
}
}
}
The main difference is that this query uses a match query to do that fulltext search. You don't need to specify any wildcards since your text fields are analyzed.
This will return the following:
{
...
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.2111092,
"hits" : [
{
"_index" : "gupta",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.2111092,
"_source" : {
"id" : 12302,
"name" : "gupta",
"mobile" : "98775422"
}
},
{
"_index" : "gupta",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.160443,
"_source" : {
"id" : 34501,
"name" : "sree gupta",
"mobile" : "98775421"
}
}
]
}
}
Now the two documents have different scores due to Field length normalization. As stated in this article about elasticsearch scoring a term match found in a field with a low number of total terms is going to be more important than a match found in a field with a large number of terms.
I hope I could help you.

Update the document by separating array into objects using the string as first object in any array

I have a document like below
{
"_id" : ObjectId("5d0768f50557b958f0c6c9cf"),
"list" : [
"abc",
"xyz",
"mno"
],
"timestamp" : "2019-06-17T10:18:29.986Z"
}
I need to update it like this below
{
"_id" : ObjectId("5d07711dbf557c3d1878ff97"),
"list" : [
{
"name" : "abc",
"type" : "car",
"color" : "red"
},
{
"name" : "xyz",
"type" : "bike",
"color" : "black"
},
{
"name" : "mno",
"type" : "auto",
"color" : "blue"
}
],
"timestamp" : "2019-06-17T10:53:17.537Z"
}
Here I need to add two more fields i.e., "type" & "color" including "name" as shown in above code.
Is it good to use MongoDB aggregation as I need to deal with array and objects.
Aggregation is not the answer here, when you need to update your data you need use update methods
For example for your case:
db.collection.updateOne(
{_id: ObjectId("5d07711dbf557c3d1878ff97")},
{
$set: {
time_stamp: Date.now()
},
$push: {
list: {$each:
[{
"name" : "xyz",
"type" : "bike",
"color" : "black"
},
{
"name" : "mno",
"type" : "auto",
"color" : "blue"
}]},
}
}
)

Adding document under nested documents

I need to add one more address like address.2._id,type,etc...:
{
"address" : {
"1" : {
"_id" : ObjectId("5a570f3d422c8223bac22dca"),
"type" : "Primary",
"street" : "58,Jones road",
"area" : "Saidapet",
"city" : "Chennai",
"pincode" : "600015",
"state" : "Tamil nadu",
"country" : "India"
}
}
}
How do I insert a particular document under a nested document?

How to get grouped facet result from Amazon CloudSearch with structured query

I am trying to get grouped facet information in following situation :
When query requests cars with certain makes (e.g) HONDA or MAZDA), with make and model facet information then query would be like
q={or "make":"HONDA" "make":"MAZDA"}&facet.make={}&facet.model={}
Then, its facet result would be like:
"make" : {
"buckets" : [{
"value" : "HONDA",
"count" : 200
}, {
"value" : "MAZDA",
"count" : 100
}
]
},
"model_display" : {
"buckets" : [{
value" : "6",
"count" : 20
}, {
"value" : "2",
"count" : 30
},
{
"value" : "3",
"count" : 50
},
"value" : "CIVIC",
"count" : 100
}, {
"value" : "ACCORD",
"count" : 50
},
{
"value" : "CR-V",
"count" : 50
},
}]
}
However, I really wonder if there is any way to get facet result like following:
"model_display" : {
"buckets" : [{
"HONDA":{
"value" : "CIVIC",
"count" : 100
}, {
"value" : "ACCORD",
"count" : 50
},{
"value" : "CR-V",
"count" : 50
},
},
{
"MAZDA":{
"value" : "6",
"count" : 20
}, {
"value" : "2",
"count" : 30
},{
"value" : "3",
"count" : 50
},
}
]}
The only way to do this is with multiple queries, one per "make":
q=make:'HONDA'&facet.model={}
q=make:'MAZDA'&facet.model={}

Resources