2

This is my data set, which is part of a bigger json code. I want to write a query, which will match all fields inside the value chain.

Dataset:

"value_chain" : {
    "category" : "Source, Make & Deliver",
    "hpe_level0" : "gift Chain Planning",
    "hpe_level1" : "nodemand to Plan",
    "hpe_level2" : "nodemand Planning",
    "hpe_level3" : "nodemand Sensing"
},

Example:

If someone searches for "gift", the query should scan through all fields, and if there is a match, return the document.

This is something I tried, but didnt work

db.sw_api.find({ 
    value_chain: { $elemMatch: { "Source, Make & Deliver" } } 
})

1 Answers1

0

Sounds like you need to create $text index on all the text fields first since it performs a text search on the content of the fields indexed with a text index:

db.sw_api.createIndex({
    "value_chain.category" : "text",
    "value_chain.hpe_level0" : "text",
    "value_chain.hpe_level1" : "text",
    "value_chain.hpe_level2" : "text",
    "value_chain.hpe_level3" : "text"
}, { "name": "value_chain_text_idx"});

The index you create is a composite index consisting of 5 columns, and mongo will automatically create the text namespace for you by default if you don't override it. With the above, if you don't specify the index name as

db.sw_api.createIndex({
    "value_chain.category" : "text",
    "value_chain.hpe_level0" : "text",
    "value_chain.hpe_level1" : "text",
    "value_chain.hpe_level2" : "text",
    "value_chain.hpe_level3" : "text"
});

there is a potential error "ns name is too long (127 byte max)" since the text index will look like this:

"you_db_name.sw_api.$value_chain.category_text_value_chain.hpe_level0_text_value_chain.hpe_level1_text_value_chain.hpe_level2_text_value_chain.hpe_level3_text"

Hence the need to give it a name which is not too long if autogenerated by mongo.

Once the index is created, a db.sw_api.getIndexes() query will show you the indexes present:

/* 1 */
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "dbname.sw_api"
    },
    {
        "v" : 1,
        "key" : {
            "_fts" : "text",
            "_ftsx" : 1
        },
        "name" : "value_chain_text_idx",
        "ns" : "dbname.sw_api",
        "weights" : {
            "value_chain.category" : 1,
            "value_chain.hpe_level0" : 1,
            "value_chain.hpe_level1" : 1,
            "value_chain.hpe_level2" : 1,
            "value_chain.hpe_level3" : 1
        },
        "default_language" : "english",
        "language_override" : "language",
        "textIndexVersion" : 3
    }
]

Once you create the index, you can then do a $text search:

db.sw_api.find({ "$text": { "$search": "gift" } })
chridam
  • 100,957
  • 23
  • 236
  • 235