MongoDB - Contains (LIKE) query on concatenated field - mongodb

I am new in MongoDB.
I am programming an application with spring data and mongodb and I have one class with two fields: firstname and lastname.
I need one query for documents that contain one string in the full name (firstname + lastname).
For example: firstname = "Hansen David", lastname = "Gonzalez Sastoque" and I have a query to find David Gonzalez. In this example I expect there to be a match.
Concatenate two strings solves it but I don't know how to perform this.

Create a new array field (call it names) in the document and in that array put each name split by space. In your example the array would have the following contents:
hansen
david
gonzalez
sastoque
(make them all lower case to prevent case insensitivity issues)
Before you do your query, convert your input to lower case and split it by spaces as well.
Now, you can use the $all operator to achieve your objective:
db.persons.find( { names: { $all: [ "david", "gonzalez" ] } } );

You can use $where modifier in your queries:
db.users.findOne({$where: %JavaScript to match the document%})
In your case it may look like this:
db.users.findOne({$where: "this.firstname + ' ' + this.lastname == 'Gonzalez Sastoque'"})
or this:
db.users.findOne({$where: "this.firstname.match(/Gonzalez/) && this.lastname.match(/Sastoque/)"})
My last example does exactly what you want.
Update: Try following code:
db.users.findOne({$where: "(this.firstname + ' ' + this.lastname).match('David Gonzalez'.replace(' ', '( .*)? '))"})

You should split your full name into a first name and a last name, then do your query on both fields, using the appropriate MongoDB query selectors.

Related

Is there a ts (text search) function would return found string instead of boolean?

I am using PostgreSQL to find out the matched string in the article by using tsvector and tsquery.
I read the PostgreSQL manual 12.3 Controlling Text Search but nothing could help me to get the exact output I wanted.
Query:
SELECT ts_headline('english',
'The most common type of search
is to find all documents containing given query terms
and return them in order of their similarity to the
query.',
to_tsquery('query & similarity'),
'StartSel = <, StopSel = >');
ts_headline output
The most common type of search
is to find all documents containing given <query> terms
and return them in order of their <similarity> to the
<query>.
I'm looking for the only string as mentioned below:
query, similarity
If you pick delimiters for StartSel and StopSel that you are sure do not exist elsewhere in the string, then it is pretty easy to do this with a regexp.
SELECT distinct regexp_matches[1] from
regexp_matches(
ts_headline('english',
'The most common type of search
is to find all documents containing given query terms
and return them in order of their similarity to the
query.',
to_tsquery('query & similarity'),
'StartSel = <, StopSel = >'
),
'<(.*?)>','g'
);

ZF2 - How to correctly concatenate a select statement containing a CONCAT function

I'm new to Zend and to Postgres. My Users table contains a FirstName column and a LastName column.
I want to query the table using a single 'full name' string; e.g. $search = 'John Sm'.
I'm trying to use the CONCAT_WS function to concatenate the two names from the table, and then compare this with the search string.
My statement
$select->where(array('CONCAT_WS(" ", "u"."FirstName", "u"."LastName") LIKE ?' => array("%$search%")));
I've tried different combinations but can't seem to get the concatenation right.
An example of the statement I want is SELECT * FROM Users WHERE 'firstname lastname' LIKE '%john s%'
This doesn't answer your question, but have you considered making a view for this?
Did you check the latest version of the documentation?
https://framework.zend.com/manual/1.12/en/zend.db.statement.html
If you use array as parameter in your $select->where() it is interpreted as pairs ['column1' => 'value', 'column2' => 'value']. In this solution you can't use functions and combined parts of query.
You can use Zend\Db\Sql\Predicate\Literal(), eg.:
$select->where
->literal('CONCAT_WS(" ", "u"."FirstName", "u"."LastName") LIKE \'%word%\'')
or use Zend\Db\Sql\Predicate\Expression(), eg.:
$select->where
->expression('CONCAT_WS(" ", "u"."FirstName", "u"."LastName") LIKE \'%?%\'', $word)
(second parameter can bee array if variables is more)
In this solution you can build sql WHERE using the same method
$select->where
->equalsTo()
->or
->greatherThan()
->and
->like()
->nest()
->lessThan()
->or
->literal()
->unnest()
...
https://framework.zend.com/manual/2.2/en/modules/zend.db.sql.html#id7
Also you can build as Zend\Db\Sql\Where / Zend\Db\Sql\Predicate as eg.:
$where = new Where();
$where->equalsTo();// and more, more, more, with sub-where inclusive
$select->where->predicate($where);

is there any feature of aliasing fields and setting defaults value for a field in mongo db while fetching results without aggregations?

1) select f1 as field_one from table;
so f1 is aliased to field_one.
2) select decode(f1, 1,one, 2, two, 3, three, 'Not a valid range' ) from table.
so for value of f1 query returns
1 One
2 Two
3 Three
else
Not a valid range
#Ankita, In Aggregation framework you have following two to address the requested features:
Aliasing: You can use $project to assign a new name - http://docs.mongodb.org/manual/reference/operator/aggregation/project/
db.coll.aggregate([{"$project": {"field_one": "$f1"}])
Decode: You should be able to use combination of $concat and $cond to the put a decode kind of statement. You can find more details bout the cond and concat in the MongoDB documentation at http://docs.mongodb.org/manual/reference/operator/aggregation/cond/ and http://docs.mongodb.org/manual/reference/operator/aggregation/concat/
db.coll.aggregate([{$project: {decode_fields: {"$concat": [{"$cond": [, , ] }, {....}] } } }])
If you're doing a query to insert the results into another collection or database, you can manipulate the way each line looks line inside the forEach function. Take a look:
db.getCollection('yourCollection').find({
property: {
$in: [ 71038, 41438 ]
}}
).forEach(function(line) {
line.id = NumberInt(line.id);
line.alteredProperty = line.property;
delete line.property;
line.updatedAt = line.meta.updatedAt;
line.createdAt = line.meta.createdAt;
delete line.meta;
db.otherCollections.insert(line);
})
Is this of any help? :)

mongoskin select special fields rather than all

I'm looking for a way to get special fields from mongoskin find function. in other words in SQL lang we say select column1,column2,column3 from mytable rather than select *
currently my query is like below and i want to get specify the fields that I'm looking for rather the the whole json object.
db.collection('collacta').find().toArray(function(err, result) {
if (result) {
...
} else {
...
};
});
thanks
For getting the projection of fields, you should pass the DBObject for projection,
DBCursor cursor = collection.find(query, projectionQuery);
The projection is The DBObject in form of key-value pair. where,
key is the name of field you want to project. value can be either 0 or 1.
0 - means exclude the particular column from result set.
1 - means include the particular column in result set.
For more info, see here.

Search database using Entity Framework. LIKE operator

I want to search one of my tables using Entity Framework 5. I don't know how many words there are in the query, but I want to match all of them.
query = hello
SELECT * FROM [table] WHERE [column] LIKE '%hello%'
query = hello world
SELECT * FROM [table] WHERE [column] LIKE '%hello%' AND [column] LIKE '%world%'
I know the function PATINDEX , but it doesn't work good enough. Why? I'll show you:
SELECT * FROM person WHERE PATINDEX('%test%.com%', email)>0
will match "test#email.com", but if the search word are ordered the other way, it will not find this person:
SELECT * FROM person WHERE PATINDEX('%.com%test%', email)>0
What is the most efficient way to create this query using EF?
using linq to entities you can use .Contains to do the equivilant in SQL
table(x => x.column).Where(y => y.ColumnName).Contains("hello");
Sorry forgot the where clause that should work.
You can build the query in a foreach loop:
var words = new[] {"com", "test"};
var table = <your initial DbSet or ObjectSet>
foreach (var word in words)
{
string word1 = word; // prevent modified closure.
table = table.Where(x => x.column.Contains(word1));
}
var result = table.ToList(); // Enumerate the composed linq query.
The Contains function translates to LIKE with the search term enclosed in % characters.