Nested Query/Select for MongoDB - javascript

I'm trying to query my MongoDB structure, specifically the users table to get a specific field, address, but am having difficulty because I'm not sure how to access something a couple levels in users > emails > address:
{
"_id": "BkWk7hq4MRyMAyK4mm",
"createdAt": ISODate("2015-11-15T19:46:41.633Z"),
"services": {
"password": {
"bcrypt": "$2a$10$voVzU3pIVZBd1bfJf1oX4.OMPnzi8zXawYY5REtovPayBJL7dZLWSC"
},
"resume": {
"loginTokens": []
}
},
"emails": [{
"address": "brutus#example.com",
"verified": false,
"provides": "default"
}],
"roles": {
"J8Bhq3uTtdgwZdx3rz": ["guest", "account/profile"]
}
} {
"_id": "3qfCgFz9r5wKjnmymQ",
"createdAt": ISODate("2015-12-15T19:49:05.236Z"),
"emails": [],
"roles": {
"J8aBhq3uTtdgwZx3rz": ["anonymous", "guest"]
},
"services": {
"resume": {
"loginTokens": [{
"when": ISODate("2015-12-15T19:49:05.280Z"),
"hashedToken": "c1ybS3U3+GeC8ZNzGQ3WOctWpudQvv4vND6EzlRygtCQ="
}]
}
}
}
I was trying to use the following:
db.users.find( { emails: { address : "brutus#example.com" } } )

You can query nested objects with dot notation.
db.users.find( { 'emails.address' : "brutus#example.com" } )
Your query is correct but it is querying documents for a complete match. So if your emails field had only address field it would work.
With dot notation you can check just one embedded field for matching.
Take a look at the documentation.

Related

how to fetch items if any search keyword matched?

I have this document in my elastic DB.I am using this package
https://www.npmjs.com/package/#elastic/elasticsearch
I am searching on title.
I am doing like this.
const result= await client.search({
index: 'products',
"query": {
"bool": {
"should": [
{
"wildcard": { "title": "*" + search + "*" }
}
],
"minimum_should_match": 1
}
}
when I search "title" this issue . it give me one result but When I am seacrhing i have issue . it is giving zero or 0 result.why ? is it possible to fetch that data.issue keyword is present in first collection why it is not picking ?
[
{
"_index": "products",
"_id": "wZRh3n8Bs9qQzO6fvTTS",
"_score": 1.0,
"_source": {
"title": "laptop issues",
"description": "laptop have issue present in according"
}
},
{
"_index": "products",
"_id": "wpRh3n8Bs9qQzO6fvzQM",
"_score": 1.0,
"_source": {
"title": "buy mobile",
"description": "mobile is in Rs 250"
}
},
{
"_index": "products",
"_id": "w5Rh3n8Bs9qQzO6fvzTz",
"_score": 1.0,
"_source": {
"title": "laptop payment",
"description": "laptop payment is given in any way"
}
}
]
how to search on keywords? any keyword match . I need to pick that whole colloection
If you want to match only some of the word from query then you can use match query with operator set to or.
{
"query": {
"match": {
"title": {
"query": "i have issues",
"operator": "or"
}
}
}
}
Update
To run the query which you mentioned in comment, You can use match_bool_prefix query.
{
"query": {
"match_bool_prefix": {
"title": {
"query": "i have issu"
}
}
}
}

How to add preference to mutliple fields in elastic search query?

I have the following data:
makeStr: xerox
modelStr: Designjet 1050C
I want it to match
xerox
Designjet 1050C Plus Printer
but it is matching
canon
DesignJet 1050C
and currently I have this query
"query": {
"bool": {
"should":
{
"multi_match": {
"query": modelStr,
"type": "most_fields",
"fields": ['model.alphanum']
}
}
,
"filter": [
{
"match": {
"make.blur": makeStr
}
},
{
"match": {
"model.blur": modelStr
}
}
]
}
},
"functions": [{
"field_value_factor": {
"field": "isMpsSupported",
"factor": 1,
"missing": 0
}
}],
"boost_mode": "sum"
}
How do I give preference for makeStr such that it considers both makeStr and modelStr during search.
More preference can be given by using boost. Refer here
Something like makeStr^2 should work.

Alphabetical sort using elasticsearch

I wounder if there any way or setting to perform an alphabetical sort in elasticsearch. I've got a field and I want to perform sort in descending order over it. Elastic performs it lexicographically. What I get:
Company name
Customer name
company address
What I want to get:
Company name
company address
Customer name
I found that I can create a custom analyser, but maybe there can be a better option?
use multifields to index the text field as lowercased keyword with fielddata true where you can sort.
{
"settings": {
"analysis": {
"analyzer": {
"keyword_lowercase": {
"tokenizer": "keyword",
"filter": ["lowercase"]
}
}
}
},
"mappings": {
"my_type": {
"properties": {
"text": {
"type": "text",
"fields": {
"raw": {
"type": "text",
"analyzer": "keyword_lowercase",
"fielddata": true
}
}
}
}
}
}
}
Query
{
"sort": [
{
"text.raw": {
"order": "asc"
}
}
]
}

Best way to filter if a field present in nested object in elasticsearch exists?

I have 1,000,000 contacts which are from different groups. For example
{"gps_id": [{"gid": "G1"},{"gid": "G2"}],"is_active": true,"contact": "c1"}
{"gps_id": [{"gid": "G2"}],"is_active": true,"contact": "c2"}
....
{"gps_id": [{"gid": "G1"},{"gid": "G2"}],"is_active": true,"contact": "c1000000"}
Consider G1 has 500,000 contacts, G2 has 1,000,000 contacts out of it 500,000 contacts which are already present in G1.
I want to filter above document object based on the condition,
"fetch unique contact from all respective group by group id".
I tried Elastic script query as below. But it doesn't work:
{
"query": {
"bool": {
"must" : {
"script" : {
"script" : {
"inline": "for (int i = 0; i < params.gps_id.length; ++i) {ctx._source.gps_id.add(params.gps_id[i]) }",
"lang": "painless",
"params": {
"gps_id": [
{
"gid": "G1"
},
{
"gid": "G2"
}
]
}
}
}
},
"must": [
{
"match": {
"is_active": true
}
},
{
"nested": {
"path": "gps_id",
"query": {
"bool": {
"must": [
{
"match": {
"gps_id.gid": "G1"
}
}
]
}
}
}
}
]
}
}
}
Here Group and its contact may increase in size.
Please suggest best way to implement it using Elasticsearch -5.1.2

Replace array element from rethinkdb if it exists,or else insert

{
"LOGIN": "ABC",
"MESSAGE_UNPROCESSED": [
{
"DATE": "20160219",
"MESSAGE": [
{
"address": "XYZ",
"date": "1468385398746"
},
{
"address": "PQR",
"date": "1468385398746"
}
]
},
{
"DATE": "20160220",
"MESSAGE": [
{
"address": "LMN",
"date": "1468385398746"
},
{
"address": "JXT",
"date": "1468385398746"
}
]
}
],
"id": "e1705cae-2a57-42b3-af2e-8458ae9a43bb"
}
I want to add message into the field where Login is ABC if DATE doesn't exist or if it exist I want to replace the entire object from doc
I tried this :
r.db('usersData').table('smsRaw').filter(function (row) {
return row('MESSAGE_UNPROCESSED')('DATE').contains('20160222').replace({"DUMP":"DUMP"})
})
error: Cannot nest writes or meta ops in stream operations. Use FOR_EACH instead in:
r.db("usersData").table("smsRaw").filter(function(var_13) {
return var_13("MESSAGE_UNPROCESSED")("DATE").contains("20160222").replace({"DUMP": "DUMP"});
})
so if records {"DATE":"2016018","MESSAGE":[{"address":"abc","Date":"121212"}]}
if this record doesn't exist in MESSAGE_UNPROCESSED it should be added using set_insert or else if date is existing like 2016020 then entire element from array should be replaced
r.db('usersData').table('smsRaw').get("7cd66671-bb01-483d-a148-12ed1b7c2d31").update(function(row) {
return {
MESSAGE_UNPROCESSED: r.branch(
row("MESSAGE_UNPROCESSED")('DATE').eq('20160222'),
row("MESSAGE_UNPROCESSED")('MESSAGE').merge({"DUMP":"DUMP"}),
row("MESSAGE_UNPROCESSED")('MESSAGE').replace({"NEW":"NEW"})
)
}
})
Cannot nest writes
I want to do this manipulation using python

Categories