How can I perform search operations on type Array of numbers?
Hi @Sagar942150 and welcome in the MongoDB Community !
Please provide an example of your document and expected result if you want a detailed answer. It’s too vague.
Here is an example based on what I understand from your question:
test:PRIMARY> db.c.insert({array:[1,2,3]})
WriteResult({ "nInserted" : 1 })
test:PRIMARY> db.c.find({array:1})
{ "_id" : ObjectId("5f84717525fa89f1696c3941"), "array" : [ 1, 2, 3 ] }
Here are more resources that hopefully will help you:
- https://docs.mongodb.com/manual/tutorial/query-arrays/
- https://docs.mongodb.com/manual/reference/operator/query-array/
I hope this helps.
Cheers,
Maxime.
@MaBeuLux88 He speaking about Atlas Search not MongoDB
@Sagar942150 Today we cannot search in array of number in $search.
You have to convert your number array to string array.
Like this.
[1,2,3] => ['1','2','3']
Make a mappings for search like string:
{
"mappings": {
"dynamic": false,
"fields": {
"ArrayNumbersField": {
"analyzer": "lucene.keyword",
"searchAnalyzer": "lucene.keyword",
"type": "string"
}
}
}
}
Make $search with filter for my example and every number you want to search add new filter:
This query will find all documents with as minimum 1 or 2 in “ArrayNumbersField” ( You can update minimumShouldMatch if you want all number required for your search :
[
{
"$search": {
"index": "SearchIndex1",
"compound": {
"filter": [
{
"compound": {
"should": [
{
"phrase": {
"path": "ArrayNumbersField",
"query": "1"
}
},
{
"phrase": {
"path": "ArrayNumbersField",
"query": "2"
}
}
],
"minimumShouldMatch": 1
}
}
]
}
}
}
]
I hope this will help you
Hi, Thanks for replying. Actually my question is for mongodb Atlas search query as per there documentation we can’t apply search on array of number type is there a way we can deal with such scenario.
It didn’t work for me my collection having a property as grades:[1, 2] it won’t return anything
Just convert this colum of array of number, by array of string. ( with all documents in your collection )
And when you insert new document dont forget to convert your array of number !
[1,2] => ['1','2']
It’s same just need to convert ( String Value) when you make your query to get numbers ( Numeric Value ).
And for make search and get array of numeric value, you can use aggregation pipeline to make your query -
- $search with $compound and $phrase ( like my first example )
- $project with $map and $toInt. With this your final result was array of numeric value !
Oops!
Looks like I got tricked and I read too fast here !
Actually, the search should return something with reference to the above code.
$search with $compound and $phrase — It is not working
Wait 1 hour i will make you a full example
Sure, will wait for your response!!!
Sorry for time
I have created new collections with two documents:
{"name":"document1","array":["1","2","3"]}
{"name":"document2","array":["3","4","5"]}
Make search Index mappings:
{
"mappings": {
"dynamic": false,
"fields": {
"array": {
"analyzer": "lucene.keyword",
"searchAnalyzer": "lucene.keyword",
"type": "string"
}
}
}
}
And make an aggregation with searching 2 and 4:
[{$search: {
index: 'default',
compound: {
filter: [
{
compound: {
should: [
{
phrase: {
path: 'array',
query: '2'
}
},
{
phrase: {
path: 'array',
query: '4'
}
}
],
minimumShouldMatch: 1
}
}
]
}
}}]
This return my two documents:
And to get Int value in result array of number you can use $project in your pipeline like this
[{$search: {
index: 'default',
compound: {
filter: [
{
compound: {
should: [
{
phrase: {
path: 'array',
query: '2'
}
},
{
phrase: {
path: 'array',
query: '4'
}
}
],
minimumShouldMatch: 1
}
}
]
}
}}, {
$project: {
name: 1,
array:
{
$map:
{
input: "$array",
as: "grade",
in: { $toInt: "$$grade" }
}
}
}
}]
I cant do more to help you now
It’s ok things take time Thank you for your help but actually as I previously said my collection is having array of number array = [1,2,3,4,5] and I have to perform an operation on this array
You juste have to convert all your documents like this:
array = [1,2,3,4,5] => array = ['1','2','3','4','5']
I will give you my scrypt python to do this ( You can change query object to apply on specific documents ! )
query = {}
print(lots.count(query))
def idlimit(page_size, skip=None, query=None):
"""Function returns `page_size` number of documents after last_id
and the new last_id.
"""
if query is None:
query = {}
if skip is None:
cursor = lots.find(query).limit(
page_size)
else:
cursor = lots.find(query).skip(skip).limit(page_size)
data = [x for x in cursor]
if not data:
return None, None
if skip is None:
skip = page_size
else:
skip += page_size
return data, skip
data, skip = idlimit(100, query=query)
count = 0
while skip is not None:
if data is not None:
for item in data:
if len(item['array']) > 0:
array = list(map(str, item['array']))
lots.update_one({"_id": item['_id']},
{'$set': {'array': array}})
count += len(data)
data, skip = idlimit(100, skip=skip, query=query)
print(count)
Thanks !!! I have added a duplicate field with array of string
Yes this was another solution also
No problem !
This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.