Mongo Atlas Search Index numeric field exact match search - mongodb

We are using MongoDB Atlas Search Indexes to query and filter the documents list. consider below document.
{_id:5sfgdfgf2c46e0fb00019bdecc,
user_id:4996,
bom_number:"112",
name:"test"}
Created default Index:
{
"mappings": {
"dynamic": false,
"fields": {
"user_id": {
"type": "string"
}
}
}
}
Query:
{
text: {
query: ["4996","3888"],
path: 'user_id'
}
}
It is not returning any documents. Can anyone please guide. I know we actually stored user_id as numeric form and I tried indexing and querying the field as String. Please help me out and suggest correct way of querying mongo atlas numeric field with multiple values.

$search is what you need to use to query using the index that you have created and you also need to mention the name of the index in the query.
The below draft might help you:
$search:{
{
index: "index_name_created_from_atlas_search",
text: {
query: "<actual data you need to search>",
path: "<field_name>"
}
}
}
And based on your example, if you want to have multiple conditions with the search, you can refer to official documentation here of all sorts of multiple conditions you can integrate with the $search aggregation using the compound operator.

Related

mongodb update an existing field without overwritting

{
questions: {
q1: "",
}
}
result after updating:
{
questions: {
q1: "",
q2: ""
}
}
I want to add q2 inside questions, without overwritting what's already inside it (q1).
One solution I found is to get the whole document, and modify it on my backend, and send the whole document to replace the current one. But it seems really in-effiecient as I have other fields in the document as well.
Is there a query that does it more efficiently? I looked at the mongodb docs, didn't seem to find a query that does it.
As turivishal said, you can use $set like this
But you also can use $addFields in this way:
db.collection.aggregate([
{
"$match": {
"questions.q1": "q1"
}
},
{
"$addFields": {
"questions.q2": "q2"
}
}
])
Example here
Also, reading your comment where you say Cannot create field 'q2' in element {questions: "q1"}. It seems your original schema is not the same you have into your DB.
Your schema says that questions is an object with field q1. But your error says that questions is the field and q1 the value.

How to change attribute name of the embed type?

How I can change the name of the embed type by query $rename?
{ list_name: [{ name_1: String }] } => { list_name: [{ name_2: String }] }
I tried db.getCollection('test').updateMany({}, { $rename: { 'list_name.name_1': 'name_2' }})
But it's throwing an error: WriteError: cannot use the part (list_name of list_name.name_1) to traverse the element ({list_name: [ { name_1: "test" } ]})
$rename does not work if these fields are in array elements
Refer
To achieve, you need $unset and $set document by document. You can use bulkwrite also.
list_name is an array. Hence $rename didn't work.
When I search, I get this. You can refer the second answer if you have less number of docs.
Else, you need to use either bulk write or mongo dump options.

MongoDB: using indexes on multiple fields or an array

I'm new with mongo
Entity:
{
"sender": {
"id": <unique key inside type>,
"type": <enum value>,
},
"recipient": {
"id": <unique key inside type>,
"type": <enum value>,
},
...
}
I need to create effective seach by query "find entities where sender or recipient equal to user from collection" with paging
foreach member in memberIHaveAccessTo:
condition ||= member == recipient || member == sender
I have read some about mongo indexes. Probably my problem can be solve by storing addional field "members" which will be array contains sender and recipient and then create index on this array
Is it possible to build such an index with monga?
Is mongo good choise to create indexes like?
Some thoughts about the issues raised in the question about querying and the application of indexes on the queried fields.
(i) The $or and two indexes:
I need to create effective search by query "find entities where sender
or recipient equal to user from collection...
Your query is going to be like this:
db.test.find( { $or: [ { "sender.id": "someid" }, { "recipient.id": "someid" } ] } )
With indexes defined on "sender.id" and "recipient.id", two individual indexes, the query with the $or operator will use both the indexes.
From the docs ($or Clauses and Indexes):
When evaluating the clauses in the $or expression, MongoDB either
performs a collection scan or, if all the clauses are supported by
indexes, MongoDB performs index scans.
Running the query with an explain() and examining the query plan shows that indexes are used for both the conditions.
(ii) Index on members array:
Probably my problem can be solve by storing addtional field "members"
which will be array contains sender and recipient and then create
index on this array...
With the members array field, the query will be like this:
db.test.find( { members_array: "someid" } )
When an index is defined on members_array field, the query will use the index; the generated query plan shows the index usage. Note that an index defined on an array field is referred as Multikey Index.

MongoDB: distinct tuples

Suppose to have a collection of MongoDB documents with the following structure:
{
id_str: "some_value",
text: "some_text",
some_field: "some_other_value"
}
I would like to filter such documents so as to obtain the ones with distinct text values.
I learned from the MongoDB documentation how to extract unique field values from a collection, using the distinct operation. Thus, by performing the following query:
db.myCollection.distinct("text")
I would obtain an array containing the distinct text values:
["first_distinct_text", "second_distinct_text",...]
However, this is not the result that i would like to obtain. Instead, I would like to have the following:
{ "id_str": "a_sample_of_id_having_first_distinct_text",
"text": "first_distinct_text"}
{ "id_str": "a_sample_of_id_having_second_distinct_text",
"text": "second_distinct_text"}
I am not sure if this can be done with a single query.
I found a similar question which, however, do not solve fully my problem.
Do you have any hint on how to solve this problem?
Thanks.
You should look into making an aggregate query using the $group stage, and probably using the $first operator.
Maybe something along the lines of:
db.myCollection.aggregate([{ $group : { _id : { text: "$text"},
text: { $first: "$id_str" }
}
}])
try:
db.myCollection.aggregate({$group: {_id: {'text': "$text", 'id_str': '$id_str'}}})
More information here: http://docs.mongodb.org/manual/reference/method/db.collection.aggregate/

How to ignore a certain field during search in MongoDB

suppose I have a MongDB record like below:
{
name:"name",
streams: [
{user:"user0", name:"name0", locked:true},
{user:"user1", name:"name1", locked:true},
{user:"user2", name:"name2", locked:false}
}
}
I want to find all records that have user0 and name0 in the streams field, but I don't care about the locked field
find({streams:{user:"user0", name:"name0"}}) doesn't work, since the locked field is not specified.
Thank You,
Gary
You are looking for the $elemMatch operator which allows you to select the fields from a sub-document in an array that match your conditions:
db.collection.find({
"streams": { "$elemMatch": { "user": "user0", "name": "name0"} }
})
Take some time to go through the Query Operators in the manual. There are lots of useful operations there.