Frage

How do I search by a query expression in MongoDB? Something like Lastname+Firstname, where Lastname and Firstname are two separate fields? The search string would then be SmithJohn. Is this possible? Can I still take advantage of indexing?

The indexes are defined like ensureIndex({LastName:1, FirstName:1},{unique:true})

I should mention that this will be the index of the collection. I actually, more importantly, will need to be able to find the data (which is the full match of the index) without knowing which collection or index I'm dealing with and get it all using the collection name (which is supplied). It might be a simple or compound index, but doesn't need to be anything else. One collection has the Date_1, another has Lastname_1_Firstname_1 for the index.

A typical request looks like /col/people/key/SmithJohn. I have a few simple indexes as well, like /col/events/key/2014-05-05.

Just a side note. With ensureIndex({LastName:1, FirstName:1},{unique:true}), will a name like Matt Hat conflict with Mat That (notice the T).

War es hilfreich?

Lösung

So pretty much from how I commented, I'm a little baffled by your use case, or interpretation of in the sense of needing to join the strings. The unique index you specify should work perfectly:

db.collection.ensureIndex({"LastName":1, "FirstName":1},{ "unique":true })

As long as you are feeding the correct parameters to .find() then this is just fine:

db.collection.find({ "LastName": "Smith", "FirstName": "John" })

So your problem seems to be one of splitting this up in your API enpoints. This is actually more of a language implementation approach, but some general ones in JavaScript are:

Split the input with a regular expression:

var param = "SmithJohn";
results = param.split(/(?=[A-Z][^A-Z])/); // yields [ "Smith", "John" ]

var obj = db.collection.findOne({ 
    "LastName": results[0], 
    "FirstName": results[1]
})

Have an endpoint that accepts the parameters in the path:

app.get("/col/people/lastname/:LastName/firstname/:FirstName"), 
  function(req,res) {

    var obj = db.collection.findOne( req.params );

Encode the data in the request payload

Client:

$.ajax({ 
    type: "GET", 
    headers: { "Content-type": "application/json" }, 
    url: "/col/people/query", 
    data: JSON.stringify({ LastName: "Smith", FirstName: "John" }) 
})

Server:

app.get("/col/people/query"), function(req,res) {

    var obj = db.collection.findOne( req.params );

So while that is all sort of pseudo-code like ( though the regex split is real and the other methods are close to real implementations ) it should give the general idea on how to handle this and there should be no need to create a concatenated key just in order to suit your current API.

As you your second question in here, there is no conflict in the unique index between names like "Matt Hat" and "Mat That" as they are not concatenated, the requirement is for both keys in combination to be considered. Most importantly, MongoDB values are considered to be "case sensitive" so the case actually does matter.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top