问:
Mongoose Model populate callback is not called when there are references
I am trying to use Mongoose's Model.populate() to convert a user ID into a User, within a substructure of a document which has been fetched through an aggregation and an unwind. I'm guessing there's either something wrong with my schema or the perhaps unwind is breaking the connection to the sub-schema.

The problem is: when there is a valid reference, the populate callback simply isn't called. When there is no substructure the callback is called, with the original document unchanged.

Structure:

I have Articles which can have none or many ArticleRatings each by a User.

I'm using two references in the ArticleRating, to relate to the Article and the User who made the rating.

Process:

The process is actually exporting the articles to a (legacy) CSV format and flattening the structure, into duplicate article rows with their user-specific ratings. Unwind is perfect for this operation, and preserve nulls retains articles with no ratings.

Debugging:

I've tried stepping deep into the Model.populate code. It gets pretty complex with all the promises and callback wrappers, but I can see that the underlying populate call isn't calling the internal callbacks either. I'm not using the promise variant - but not 100% sure if I should be? (the Mongoose docs are a bit vague on the use-cases between callbacks and promises).

I've double checked my schema, tried explicitly adding the model to the populate call (which shouldn't be needed as it's in the schema). There are no errors or exceptions, it doesn't crash.

Stepping through the code in the Chrome debugger shows the model just as I'd expect: the first few Articles have a rating.userId with a valid ObjectId, but in those cases the populate callback simply doesn't get called. The next hundred Articles have no "rating" set, and the callback gets called reliably for all of them.

So I'm guessing something I'm doing wrong is leading Model.populate down a path where it's not erroring properly?

Note: I know I could rewrite the code to use aggregate $lookup or other embedding structures rather than the foreign reference, but I'm at the final piece of a feature jigsaw and would like to get this working as-is.

This is the simplified schema:

```<code>const ArticleRatingSchema = new Schema({
    articleId: {type: Schema.Types.ObjectId, ref:'Article'},
    userId: {type: Schema.Types.ObjectId, ref:'User'},
    rating: String,
    comment: String,
});

const ArticleSchema = new Schema({
    title: String,
    rating: ArticleRatingSchema,
});
</code>```

And this is the lookup

```<code>    // Find all articles relating to this project, and their ratings.
    // Unwind does the duplicate per-user, and preserve keeps un-rated articles.
    articleModel.aggregate([
            {$match: {projectId: projectId}},
            {$lookup:{from:'articleratings', localField:'_id', foreignField:'articleId', as:'rating' }},
            {$unwind: {path:'$rating', preserveNullAndEmptyArrays:true}}
        ], (err, models) =>
    {
        if (!err) {

            models.map((article) => {

                articleModel.populate(article, {path:'rating.userId', model:'User'}, (err, article)=> {
                    // Process the article...
                    // this callback only gets called where there is NO rating in the article.
                });

            });
        }
</code>```

答:
I'm personally more than a bit baffled by where you think you are going with using $lookup in an aggregation pipeline and then wanting .populate() the results. Because asking to use .populate() essentially means that additional queries are being issued to the server in order to "emulate a join".

Therefore since $lookup actually does the "join on the server" then you really should be just using $lookup for this.

You can use .populate() and I'll show some code to show that it can be done. But it really is redundant here since you may as well just do all the work on the server.

So my best "approximation" of what you seem to have as a structure is:

articles

```<code>{
        "_id" : ObjectId("5962104312246235cdcceb16"),
        "title" : "New News",
        "ratings" : [ ],
        "__v" : 0
}
</code>```

articleratings

```<code>{
        "_id" : ObjectId("5962104312246235cdcceb17"),
        "articleId" : ObjectId("5962104312246235cdcceb16"),
        "userId" : ObjectId("5962104312246235cdcceb13"),
        "rating" : "5",
        "comment" : "Great!",
        "__v" : 0
}
{
        "_id" : ObjectId("5962104312246235cdcceb18"),
        "articleId" : ObjectId("5962104312246235cdcceb16"),
        "userId" : ObjectId("5962104312246235cdcceb14"),
        "rating" : "3",
        "comment" : "Okay I guess ;)",
        "__v" : 0
}
{
        "_id" : ObjectId("5962104312246235cdcceb19"),
        "articleId" : ObjectId("5962104312246235cdcceb16"),
        "userId" : ObjectId("5962104312246235cdcceb15"),
        "rating" : "1",
        "comment" : "Hated it :<",
        "__v" : 0
}
</code>```

users

```<code>{
        "_id" : ObjectId("5962104312246235cdcceb13"),
        "name" : "Bill",
        "email" : "bill@example.com",
        "__v" : 0
}
{
        "_id" : ObjectId("5962104312246235cdcceb14"),
        "name" : "Fred",
        "email" : "fred@example.com",
        "__v" : 0
}
{
        "_id" : ObjectId("5962104312246235cdcceb15"),
        "name" : "Ted",
        "email" : "ted@example.com",
        "__v" : 0
}
</code>```

And then the aggregate statement:

```<code>  Article.aggregate(
    [
      { "$lookup": {
        "from": ArticleRating.collection.name,
        "localField": "_id",
        "foreignField": "articleId",
        "as": "ratings"
      }},
      { "$unwind": "$ratings" },
      { "$lookup": {
        "from": User.collection.name,
        "localField": "ratings.userId",
        "foreignField": "_id",
        "as": "ratings.userId",
      }},
      { "$unwind": "$ratings.userId" },
      { "$group": {
        "_id": "$_id",
        "title": { "$first": "$title" },
        "ratings": { "$push": "$ratings" }
      }}
    ],
    (err,articles) => {
      if (err) callback(err);
      log(articles);
      callback();
    }
  )
</code>```

With the result:

```<code>  {
    "_id": "5962126f3ef2fb35efeefd94",
    "title": "New News",
    "ratings": [
      {
        "_id": "5962126f3ef2fb35efeefd95",
        "articleId": "5962126f3ef2fb35efeefd94",
        "userId": {
          "_id": "5962126f3ef2fb35efeefd91",
          "name": "Bill",
          "email": "bill@example.com",
          "__v": 0
        },
        "rating": "5",
        "comment": "Great!",
        "__v": 0
      },
      {
        "_id": "5962126f3ef2fb35efeefd96",
        "articleId": "5962126f3ef2fb35efeefd94",
        "userId": {
          "_id": "5962126f3ef2fb35efeefd92",
          "name": "Fred",
          "email": "fred@example.com",
          "__v": 0
        },
        "rating": "3",
        "comment": "Okay I guess ;)",
        "__v": 0
      },
      {
        "_id": "5962126f3ef2fb35efeefd97",
        "articleId": "5962126f3ef2fb35efeefd94",
        "userId": {
          "_id": "5962126f3ef2fb35efeefd93",
          "name": "Ted",
          "email": "ted@example.com",
          "__v": 0
        },
        "rating": "1",
        "comment": "Hated it :<",
        "__v": 0
      }
    ]
  }
</code>```

Where it does not make sense to "populate" the references to the "articleId" on the "ratings" themselves. But we have indeed "populated" the "ratings" to the article, and the "user" for each rating.

Example Listing

Shows it both ways, using .populate() ( after $lookup ) like you are trying, and also just using the plain $lookup.

Methods use both "plain promises"  and alternate with async.map:

```<code>const async = require('async'),
      mongoose = require('mongoose'),
      Schema = mongoose.Schema;

mongoose.Promise = global.Promise;
mongoose.set('debug',true);

mongoose.connect('mongodb://localhost/publication');

const userSchema = new Schema({
  name: String,
  email: String
});

const User = mongoose.model('User', userSchema);

const articleRatingSchema = new Schema({
  articleId: {type: Schema.Types.ObjectId, ref:'Article'},
  userId: {type: Schema.Types.ObjectId, ref:'User'},
  rating: String,
  comment: String,
});

const articleSchema = new Schema({
  title: String,
  ratings: [articleRatingSchema]
})

const Article = mongoose.model('Article', articleSchema);
const ArticleRating = mongoose.model('ArticleRating', articleRatingSchema);

function log(data) {
  console.log(JSON.stringify(data,undefined,2))
}

const userData = [
  { name: 'Bill', rating: 5, comment: 'Great!' },
  { name: 'Fred', rating: 3, comment: 'Okay I guess ;)' },
  { name: 'Ted',  rating: 1, comment: 'Hated it :<' }
];

async.series(
  [
    // Clean data
    (callback) =>
      async.each(mongoose.models,(model,callback) =>
        model.remove({},callback),callback),

    // Insert data
    (callback) =>
      async.waterfall(
        [
          // User and article
          (callback) =>
            async.parallel(
              {
                "users": (callback) =>
                  User.create(
                    ["Bill", "Fred", "Ted"].map( name =>
                      ({ name, email: `${name.toLowerCase()}@example.com` })
                    ),
                    callback
                  ),

                "article": (callback) =>
                  Article.create({ title: "New News" },callback)
              },
              callback
            ),

          // Article Ratings
          (data,callback) =>
            ArticleRating.create(
              data.users.map( u => ({
                articleId: data.article._id,
                userId: u._id,
                rating: userData.find( ud => ud.name === u.name ).rating,
                comment: userData.find( ud => ud.name === u.name ).comment
              })),
              callback
            )
        ],
        callback
      ),

    // $lookup and populate async.map
    (callback) =>
      Article.aggregate(
        [
          { "$lookup": {
            "from": ArticleRating.collection.name,
            "localField": "_id",
            "foreignField": "articleId",
            "as": "ratings"
          }}
        ],
        (err,articles) => {
          if (err) callback(err);
          async.map(
            articles.map( a => new Article(a) ),
            (article,callback) =>
              async.map(
                article.ratings,
                (rating,callback) =>
                  ArticleRating.populate(rating,{ path: 'userId' },callback),
                (err,ratings) => {
                  if (err) callback(err);
                  article.ratings = ratings
                  callback(null,article)
                }
              ),
            (err,articles) => {
              if (err) callback(err);
              log(articles);
              callback();
            }
          )
        }
      ),

    // $look and populate Promise
    (callback) =>
      Article.aggregate(
        [
          { "$lookup": {
            "from": ArticleRating.collection.name,
            "localField": "_id",
            "foreignField": "articleId",
            "as": "ratings"
          }}
        ]
      )
      .then(articles =>
        Promise.all(
          articles.map( a => new Article(a) ).map(article =>
            new Promise((resolve,reject) => {
              Promise.all(
                article.ratings.map( rating =>
                  ArticleRating.populate(rating,{ path: 'userId' })
                )
              ).then(ratings => {
                article.ratings = ratings;
                resolve(article);
              }).catch(reject)
            })
          )
        )
      )
      .then(articles => {
        log(articles);
        callback();
      })
      .catch(err => callback(err)),

    // Plain $lookup
    (callback) =>
      Article.aggregate(
        [
          { "$lookup": {
            "from": ArticleRating.collection.name,
            "localField": "_id",
            "foreignField": "articleId",
            "as": "ratings"
          }},
          { "$unwind": "$ratings" },
          { "$lookup": {
            "from": User.collection.name,
            "localField": "ratings.userId",
            "foreignField": "_id",
            "as": "ratings.userId",
          }},
          { "$unwind": "$ratings.userId" },
          { "$group": {
            "_id": "$_id",
            "title": { "$first": "$title" },
            "ratings": { "$push": "$ratings" }
          }}
        ],
        (err,articles) => {
          if (err) callback(err);
          log(articles);
          callback();
        }
      )
  ],
  (err) => {
    if (err) throw err;
    mongoose.disconnect();
  }
);
</code>```

Full Output

```<code>Mongoose: users.remove({}, {})
Mongoose: articles.remove({}, {})
Mongoose: articleratings.remove({}, {})
Mongoose: users.insert({ name: 'Bill', email: 'bill@example.com', _id: ObjectId("596219ff6f73ed36d868ed40"), __v: 0 })
Mongoose: users.insert({ name: 'Fred', email: 'fred@example.com', _id: ObjectId("596219ff6f73ed36d868ed41"), __v: 0 })
Mongoose: users.insert({ name: 'Ted', email: 'ted@example.com', _id: ObjectId("596219ff6f73ed36d868ed42"), __v: 0 })
Mongoose: articles.insert({ title: 'New News', _id: ObjectId("596219ff6f73ed36d868ed43"), ratings: [], __v: 0 })
Mongoose: articleratings.insert({ articleId: ObjectId("596219ff6f73ed36d868ed43"), userId: ObjectId("596219ff6f73ed36d868ed40"), rating: '5', comment: 'Great!', _id: ObjectId("596219ff6f73ed36d868ed44"), __v: 0 })
Mongoose: articleratings.insert({ articleId: ObjectId("596219ff6f73ed36d868ed43"), userId: ObjectId("596219ff6f73ed36d868ed41"), rating: '3', comment: 'Okay I guess ;)', _id: ObjectId("596219ff6f73ed36d868ed45"), __v: 0 })
Mongoose: articleratings.insert({ articleId: ObjectId("596219ff6f73ed36d868ed43"), userId: ObjectId("596219ff6f73ed36d868ed42"), rating: '1', comment: 'Hated it :<', _id: ObjectId("596219ff6f73ed36d868ed46"), __v: 0 })
Mongoose: articles.aggregate([ { '$lookup': { from: 'articleratings', localField: '_id', foreignField: 'articleId', as: 'ratings' } } ], {})
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed40") ] } }, { fields: {} })
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed41") ] } }, { fields: {} })
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed42") ] } }, { fields: {} })
[
  {
    "_id": "596219ff6f73ed36d868ed43",
    "title": "New News",
    "__v": 0,
    "ratings": [
      {
        "_id": "596219ff6f73ed36d868ed44",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed40",
          "name": "Bill",
          "email": "bill@example.com",
          "__v": 0
        },
        "rating": "5",
        "comment": "Great!",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed45",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed41",
          "name": "Fred",
          "email": "fred@example.com",
          "__v": 0
        },
        "rating": "3",
        "comment": "Okay I guess ;)",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed46",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed42",
          "name": "Ted",
          "email": "ted@example.com",
          "__v": 0
        },
        "rating": "1",
        "comment": "Hated it :<",
        "__v": 0
      }
    ]
  }
]
Mongoose: articles.aggregate([ { '$lookup': { from: 'articleratings', localField: '_id', foreignField: 'articleId', as: 'ratings' } } ], {})
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed40") ] } }, { fields: {} })
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed41") ] } }, { fields: {} })
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed42") ] } }, { fields: {} })
[
  {
    "_id": "596219ff6f73ed36d868ed43",
    "title": "New News",
    "__v": 0,
    "ratings": [
      {
        "_id": "596219ff6f73ed36d868ed44",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed40",
          "name": "Bill",
          "email": "bill@example.com",
          "__v": 0
        },
        "rating": "5",
        "comment": "Great!",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed45",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed41",
          "name": "Fred",
          "email": "fred@example.com",
          "__v": 0
        },
        "rating": "3",
        "comment": "Okay I guess ;)",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed46",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed42",
          "name": "Ted",
          "email": "ted@example.com",
          "__v": 0
        },
        "rating": "1",
        "comment": "Hated it :<",
        "__v": 0
      }
    ]
  }
]
Mongoose: articles.aggregate([ { '$lookup': { from: 'articleratings', localField: '_id', foreignField: 'articleId', as: 'ratings' } }, { '$unwind': '$ratings' }, { '$lookup': { from: 'users', localField: 'ratings.userId', foreignField: '_id', as: 'ratings.userId' } }, { '$unwind': '$ratings.userId' }, { '$group': { _id: '$_id', title: { '$first': '$title' }, ratings: { '$push': '$ratings' } } } ], {})
[
  {
    "_id": "596219ff6f73ed36d868ed43",
    "title": "New News",
    "ratings": [
      {
        "_id": "596219ff6f73ed36d868ed44",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed40",
          "name": "Bill",
          "email": "bill@example.com",
          "__v": 0
        },
        "rating": "5",
        "comment": "Great!",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed45",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed41",
          "name": "Fred",
          "email": "fred@example.com",
          "__v": 0
        },
        "rating": "3",
        "comment": "Okay I guess ;)",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed46",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed42",
          "name": "Ted",
          "email": "ted@example.com",
          "__v": 0
        },
        "rating": "1",
        "comment": "Hated it :<",
        "__v": 0
      }
    ]
  }
]
</code>```

Body:
I am trying to use Mongoose's Model.populate() to convert a user ID into a User, within a substructure of a document which has been fetched through an aggregation and an unwind. I'm guessing there's either something wrong with my schema or the perhaps unwind is breaking the connection to the sub-schema.

The problem is: when there is a valid reference, the populate callback simply isn't called. When there is no substructure the callback is called, with the original document unchanged.

Structure:

I have Articles which can have none or many ArticleRatings each by a User.

I'm using two references in the ArticleRating, to relate to the Article and the User who made the rating.

Process:

The process is actually exporting the articles to a (legacy) CSV format and flattening the structure, into duplicate article rows with their user-specific ratings. Unwind is perfect for this operation, and preserve nulls retains articles with no ratings.

Debugging:

I've tried stepping deep into the Model.populate code. It gets pretty complex with all the promises and callback wrappers, but I can see that the underlying populate call isn't calling the internal callbacks either. I'm not using the promise variant - but not 100% sure if I should be? (the Mongoose docs are a bit vague on the use-cases between callbacks and promises).

I've double checked my schema, tried explicitly adding the model to the populate call (which shouldn't be needed as it's in the schema). There are no errors or exceptions, it doesn't crash.

Stepping through the code in the Chrome debugger shows the model just as I'd expect: the first few Articles have a rating.userId with a valid ObjectId, but in those cases the populate callback simply doesn't get called. The next hundred Articles have no "rating" set, and the callback gets called reliably for all of them.

So I'm guessing something I'm doing wrong is leading Model.populate down a path where it's not erroring properly?

Note: I know I could rewrite the code to use aggregate $lookup or other embedding structures rather than the foreign reference, but I'm at the final piece of a feature jigsaw and would like to get this working as-is.

This is the simplified schema:

const ArticleRatingSchema = new Schema({
    articleId: {type: Schema.Types.ObjectId, ref:'Article'},
    userId: {type: Schema.Types.ObjectId, ref:'User'},
    rating: String,
    comment: String,
});

const ArticleSchema = new Schema({
    title: String,
    rating: ArticleRatingSchema,
});

And this is the lookup

    // Find all articles relating to this project, and their ratings.
    // Unwind does the duplicate per-user, and preserve keeps un-rated articles.
    articleModel.aggregate([
            {$match: {projectId: projectId}},
            {$lookup:{from:'articleratings', localField:'_id', foreignField:'articleId', as:'rating' }},
            {$unwind: {path:'$rating', preserveNullAndEmptyArrays:true}}
        ], (err, models) =>
    {
        if (!err) {

            models.map((article) => {

                articleModel.populate(article, {path:'rating.userId', model:'User'}, (err, article)=> {
                    // Process the article...
                    // this callback only gets called where there is NO rating in the article.
                });

            });
        }

Body:
I'm personally more than a bit baffled by where you think you are going with using $lookup in an aggregation pipeline and then wanting .populate() the results. Because asking to use .populate() essentially means that additional queries are being issued to the server in order to "emulate a join".

Therefore since $lookup actually does the "join on the server" then you really should be just using $lookup for this.

You can use .populate() and I'll show some code to show that it can be done. But it really is redundant here since you may as well just do all the work on the server.

So my best "approximation" of what you seem to have as a structure is:

articles

{
        "_id" : ObjectId("5962104312246235cdcceb16"),
        "title" : "New News",
        "ratings" : [ ],
        "__v" : 0
}

articleratings

{
        "_id" : ObjectId("5962104312246235cdcceb17"),
        "articleId" : ObjectId("5962104312246235cdcceb16"),
        "userId" : ObjectId("5962104312246235cdcceb13"),
        "rating" : "5",
        "comment" : "Great!",
        "__v" : 0
}
{
        "_id" : ObjectId("5962104312246235cdcceb18"),
        "articleId" : ObjectId("5962104312246235cdcceb16"),
        "userId" : ObjectId("5962104312246235cdcceb14"),
        "rating" : "3",
        "comment" : "Okay I guess ;)",
        "__v" : 0
}
{
        "_id" : ObjectId("5962104312246235cdcceb19"),
        "articleId" : ObjectId("5962104312246235cdcceb16"),
        "userId" : ObjectId("5962104312246235cdcceb15"),
        "rating" : "1",
        "comment" : "Hated it :<",
        "__v" : 0
}

users

{
        "_id" : ObjectId("5962104312246235cdcceb13"),
        "name" : "Bill",
        "email" : "bill@example.com",
        "__v" : 0
}
{
        "_id" : ObjectId("5962104312246235cdcceb14"),
        "name" : "Fred",
        "email" : "fred@example.com",
        "__v" : 0
}
{
        "_id" : ObjectId("5962104312246235cdcceb15"),
        "name" : "Ted",
        "email" : "ted@example.com",
        "__v" : 0
}

And then the aggregate statement:

  Article.aggregate(
    [
      { "$lookup": {
        "from": ArticleRating.collection.name,
        "localField": "_id",
        "foreignField": "articleId",
        "as": "ratings"
      }},
      { "$unwind": "$ratings" },
      { "$lookup": {
        "from": User.collection.name,
        "localField": "ratings.userId",
        "foreignField": "_id",
        "as": "ratings.userId",
      }},
      { "$unwind": "$ratings.userId" },
      { "$group": {
        "_id": "$_id",
        "title": { "$first": "$title" },
        "ratings": { "$push": "$ratings" }
      }}
    ],
    (err,articles) => {
      if (err) callback(err);
      log(articles);
      callback();
    }
  )

With the result:

  {
    "_id": "5962126f3ef2fb35efeefd94",
    "title": "New News",
    "ratings": [
      {
        "_id": "5962126f3ef2fb35efeefd95",
        "articleId": "5962126f3ef2fb35efeefd94",
        "userId": {
          "_id": "5962126f3ef2fb35efeefd91",
          "name": "Bill",
          "email": "bill@example.com",
          "__v": 0
        },
        "rating": "5",
        "comment": "Great!",
        "__v": 0
      },
      {
        "_id": "5962126f3ef2fb35efeefd96",
        "articleId": "5962126f3ef2fb35efeefd94",
        "userId": {
          "_id": "5962126f3ef2fb35efeefd92",
          "name": "Fred",
          "email": "fred@example.com",
          "__v": 0
        },
        "rating": "3",
        "comment": "Okay I guess ;)",
        "__v": 0
      },
      {
        "_id": "5962126f3ef2fb35efeefd97",
        "articleId": "5962126f3ef2fb35efeefd94",
        "userId": {
          "_id": "5962126f3ef2fb35efeefd93",
          "name": "Ted",
          "email": "ted@example.com",
          "__v": 0
        },
        "rating": "1",
        "comment": "Hated it :<",
        "__v": 0
      }
    ]
  }

Where it does not make sense to "populate" the references to the "articleId" on the "ratings" themselves. But we have indeed "populated" the "ratings" to the article, and the "user" for each rating.

Example Listing

Shows it both ways, using .populate() ( after $lookup ) like you are trying, and also just using the plain $lookup.

Methods use both "plain promises"  and alternate with async.map:

const async = require('async'),
      mongoose = require('mongoose'),
      Schema = mongoose.Schema;

mongoose.Promise = global.Promise;
mongoose.set('debug',true);

mongoose.connect('mongodb://localhost/publication');

const userSchema = new Schema({
  name: String,
  email: String
});

const User = mongoose.model('User', userSchema);

const articleRatingSchema = new Schema({
  articleId: {type: Schema.Types.ObjectId, ref:'Article'},
  userId: {type: Schema.Types.ObjectId, ref:'User'},
  rating: String,
  comment: String,
});

const articleSchema = new Schema({
  title: String,
  ratings: [articleRatingSchema]
})

const Article = mongoose.model('Article', articleSchema);
const ArticleRating = mongoose.model('ArticleRating', articleRatingSchema);

function log(data) {
  console.log(JSON.stringify(data,undefined,2))
}

const userData = [
  { name: 'Bill', rating: 5, comment: 'Great!' },
  { name: 'Fred', rating: 3, comment: 'Okay I guess ;)' },
  { name: 'Ted',  rating: 1, comment: 'Hated it :<' }
];

async.series(
  [
    // Clean data
    (callback) =>
      async.each(mongoose.models,(model,callback) =>
        model.remove({},callback),callback),

    // Insert data
    (callback) =>
      async.waterfall(
        [
          // User and article
          (callback) =>
            async.parallel(
              {
                "users": (callback) =>
                  User.create(
                    ["Bill", "Fred", "Ted"].map( name =>
                      ({ name, email: `${name.toLowerCase()}@example.com` })
                    ),
                    callback
                  ),

                "article": (callback) =>
                  Article.create({ title: "New News" },callback)
              },
              callback
            ),

          // Article Ratings
          (data,callback) =>
            ArticleRating.create(
              data.users.map( u => ({
                articleId: data.article._id,
                userId: u._id,
                rating: userData.find( ud => ud.name === u.name ).rating,
                comment: userData.find( ud => ud.name === u.name ).comment
              })),
              callback
            )
        ],
        callback
      ),

    // $lookup and populate async.map
    (callback) =>
      Article.aggregate(
        [
          { "$lookup": {
            "from": ArticleRating.collection.name,
            "localField": "_id",
            "foreignField": "articleId",
            "as": "ratings"
          }}
        ],
        (err,articles) => {
          if (err) callback(err);
          async.map(
            articles.map( a => new Article(a) ),
            (article,callback) =>
              async.map(
                article.ratings,
                (rating,callback) =>
                  ArticleRating.populate(rating,{ path: 'userId' },callback),
                (err,ratings) => {
                  if (err) callback(err);
                  article.ratings = ratings
                  callback(null,article)
                }
              ),
            (err,articles) => {
              if (err) callback(err);
              log(articles);
              callback();
            }
          )
        }
      ),

    // $look and populate Promise
    (callback) =>
      Article.aggregate(
        [
          { "$lookup": {
            "from": ArticleRating.collection.name,
            "localField": "_id",
            "foreignField": "articleId",
            "as": "ratings"
          }}
        ]
      )
      .then(articles =>
        Promise.all(
          articles.map( a => new Article(a) ).map(article =>
            new Promise((resolve,reject) => {
              Promise.all(
                article.ratings.map( rating =>
                  ArticleRating.populate(rating,{ path: 'userId' })
                )
              ).then(ratings => {
                article.ratings = ratings;
                resolve(article);
              }).catch(reject)
            })
          )
        )
      )
      .then(articles => {
        log(articles);
        callback();
      })
      .catch(err => callback(err)),

    // Plain $lookup
    (callback) =>
      Article.aggregate(
        [
          { "$lookup": {
            "from": ArticleRating.collection.name,
            "localField": "_id",
            "foreignField": "articleId",
            "as": "ratings"
          }},
          { "$unwind": "$ratings" },
          { "$lookup": {
            "from": User.collection.name,
            "localField": "ratings.userId",
            "foreignField": "_id",
            "as": "ratings.userId",
          }},
          { "$unwind": "$ratings.userId" },
          { "$group": {
            "_id": "$_id",
            "title": { "$first": "$title" },
            "ratings": { "$push": "$ratings" }
          }}
        ],
        (err,articles) => {
          if (err) callback(err);
          log(articles);
          callback();
        }
      )
  ],
  (err) => {
    if (err) throw err;
    mongoose.disconnect();
  }
);

Full Output

Mongoose: users.remove({}, {})
Mongoose: articles.remove({}, {})
Mongoose: articleratings.remove({}, {})
Mongoose: users.insert({ name: 'Bill', email: 'bill@example.com', _id: ObjectId("596219ff6f73ed36d868ed40"), __v: 0 })
Mongoose: users.insert({ name: 'Fred', email: 'fred@example.com', _id: ObjectId("596219ff6f73ed36d868ed41"), __v: 0 })
Mongoose: users.insert({ name: 'Ted', email: 'ted@example.com', _id: ObjectId("596219ff6f73ed36d868ed42"), __v: 0 })
Mongoose: articles.insert({ title: 'New News', _id: ObjectId("596219ff6f73ed36d868ed43"), ratings: [], __v: 0 })
Mongoose: articleratings.insert({ articleId: ObjectId("596219ff6f73ed36d868ed43"), userId: ObjectId("596219ff6f73ed36d868ed40"), rating: '5', comment: 'Great!', _id: ObjectId("596219ff6f73ed36d868ed44"), __v: 0 })
Mongoose: articleratings.insert({ articleId: ObjectId("596219ff6f73ed36d868ed43"), userId: ObjectId("596219ff6f73ed36d868ed41"), rating: '3', comment: 'Okay I guess ;)', _id: ObjectId("596219ff6f73ed36d868ed45"), __v: 0 })
Mongoose: articleratings.insert({ articleId: ObjectId("596219ff6f73ed36d868ed43"), userId: ObjectId("596219ff6f73ed36d868ed42"), rating: '1', comment: 'Hated it :<', _id: ObjectId("596219ff6f73ed36d868ed46"), __v: 0 })
Mongoose: articles.aggregate([ { '$lookup': { from: 'articleratings', localField: '_id', foreignField: 'articleId', as: 'ratings' } } ], {})
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed40") ] } }, { fields: {} })
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed41") ] } }, { fields: {} })
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed42") ] } }, { fields: {} })
[
  {
    "_id": "596219ff6f73ed36d868ed43",
    "title": "New News",
    "__v": 0,
    "ratings": [
      {
        "_id": "596219ff6f73ed36d868ed44",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed40",
          "name": "Bill",
          "email": "bill@example.com",
          "__v": 0
        },
        "rating": "5",
        "comment": "Great!",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed45",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed41",
          "name": "Fred",
          "email": "fred@example.com",
          "__v": 0
        },
        "rating": "3",
        "comment": "Okay I guess ;)",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed46",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed42",
          "name": "Ted",
          "email": "ted@example.com",
          "__v": 0
        },
        "rating": "1",
        "comment": "Hated it :<",
        "__v": 0
      }
    ]
  }
]
Mongoose: articles.aggregate([ { '$lookup': { from: 'articleratings', localField: '_id', foreignField: 'articleId', as: 'ratings' } } ], {})
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed40") ] } }, { fields: {} })
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed41") ] } }, { fields: {} })
Mongoose: users.find({ _id: { '$in': [ ObjectId("596219ff6f73ed36d868ed42") ] } }, { fields: {} })
[
  {
    "_id": "596219ff6f73ed36d868ed43",
    "title": "New News",
    "__v": 0,
    "ratings": [
      {
        "_id": "596219ff6f73ed36d868ed44",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed40",
          "name": "Bill",
          "email": "bill@example.com",
          "__v": 0
        },
        "rating": "5",
        "comment": "Great!",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed45",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed41",
          "name": "Fred",
          "email": "fred@example.com",
          "__v": 0
        },
        "rating": "3",
        "comment": "Okay I guess ;)",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed46",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed42",
          "name": "Ted",
          "email": "ted@example.com",
          "__v": 0
        },
        "rating": "1",
        "comment": "Hated it :<",
        "__v": 0
      }
    ]
  }
]
Mongoose: articles.aggregate([ { '$lookup': { from: 'articleratings', localField: '_id', foreignField: 'articleId', as: 'ratings' } }, { '$unwind': '$ratings' }, { '$lookup': { from: 'users', localField: 'ratings.userId', foreignField: '_id', as: 'ratings.userId' } }, { '$unwind': '$ratings.userId' }, { '$group': { _id: '$_id', title: { '$first': '$title' }, ratings: { '$push': '$ratings' } } } ], {})
[
  {
    "_id": "596219ff6f73ed36d868ed43",
    "title": "New News",
    "ratings": [
      {
        "_id": "596219ff6f73ed36d868ed44",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed40",
          "name": "Bill",
          "email": "bill@example.com",
          "__v": 0
        },
        "rating": "5",
        "comment": "Great!",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed45",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed41",
          "name": "Fred",
          "email": "fred@example.com",
          "__v": 0
        },
        "rating": "3",
        "comment": "Okay I guess ;)",
        "__v": 0
      },
      {
        "_id": "596219ff6f73ed36d868ed46",
        "articleId": "596219ff6f73ed36d868ed43",
        "userId": {
          "_id": "596219ff6f73ed36d868ed42",
          "name": "Ted",
          "email": "ted@example.com",
          "__v": 0
        },
        "rating": "1",
        "comment": "Hated it :<",
        "__v": 0
      }
    ]
  }
]


来源: stackexchange

问:
Semantic UI react, render dropdown/modal only when it's visible?
Is there a way to delay rendering of content of dropdown/modal until it is open?

I see they are being rendered even if they are not visible until user clicks to see its contents.

答:
The Modal component uses Portal for rendering content, while Portal renders something only if it's open. This means that the component already satisfies your conditions.

With the Dropdown component, it will be more difficult. You can control it yourself, but it means that you will need to process all events self-consciously and it will be not easy.

```<code><Dropdown open={true} options={open && options} />
</code>```

ContentLicense: CC BY-SA 3.0

Body:
The Modal component uses Portal for rendering content, while Portal renders something only if it's open. This means that the component already satisfies your conditions.

With the Dropdown component, it will be more difficult. You can control it yourself, but it means that you will need to process all events self-consciously and it will be not easy.

<Dropdown open={true} options={open && options} />


问:
How to iterate over single tuple item in array of tuples
I have an array of tuples of Int, CustomType, OtherCustomType. The array is sorted by the Int part of the tuples.

To add new elements at the correct position I wrote a binary search function to get the insertion point index.

The function returns a new tuple of Int, Bool, where Bool tells if the element is already present, and Int is either the index of the first occurrence of the new element, or the index of the first element which is larger than the new element.

The function is written genericly, and takes an array of a comparable type and a new element of the same type as arguments, so, obviously, I cannot simply pass my array of tuples.

A simple solution would be to re-organize my data so, instead of storing three values as tuples in one array, I could use three separate arrays, each of only one of the three values. I would then pass only the first array to the binary search function and then perform the desired action on all three arrays at the found index.

But is there a way to keep my data organized as tuples and pass only one element of each tuple to the function, like we are able to ignore parts of a tuple in comparisons like if tuple == (_ ,23, _) ?

Here is some sample code:

```<code>func findInsertPoint <T: Comparable> (forElement: T, inArray: [T]) -> (Int, Bool) {
    var low = 0
    var high = inArray.count

    if forElement > inArray[high-1] {
        return (high, false)
    }
    while low < high {
        let mid = (low+high)/2
        if inArray[mid] >= forElement {
            high = mid
        } else {
            low = mid+1
        }
    }
    return(low,(inArray[low] == forElement))
}
</code>```

An array of Ints works perfectly fine:

```<code>// index         0 1 2 3 4 5  6  7  8  9  10 11 12 13 14 15
var testArray = [1,2,5,7,8,11,12,12,12,15,19,22,22,26,52,56]

findInsertPoint(forElement: x, inArray: testArray)

// x = 17 returns (10,false)
// x = 19 returns (10,true)
</code>```

But my actual array looks something like this:

```<code>var testArray = [(4,"Bee",2.5),(5,"dog",1.0),(8,"dog",43.13)]
</code>```

How do I pass an array of only the first part of each tuple, but without the expensive creation of an actual new array each function call?

A possibility would be to call the function:

```<code>findInsertPoint(forElement: 7 in Array: testArray.0)
</code>```

which would be perfect, but I know this doesn't work.

Is there a Swift way to temporarily ignore members of a tuple or a struct for a function call that only accepts arrays of a single type?

If not, I know my two possibilities are:

stick to my taylored binary search, not the generic one from the code above.

divide the tuple into 3 separate arrays.

答:
This is the solution I found:

If you have an array of types which are collection types on their own, and you want to look only at a certain property of each member of the outer array, use the .map method of swift's collection type:

```<code>var testArray = [(4,"Bee",2.5),(5,"dog",1.0),(8,"dog",43.13)]
var onlyFirstProperty = testArray.map({$0.0}) // [4,5,8]
</code>```

This way you'll get a new array which consists only of the first elements of each tuple. $0.0 is shorthand syntax for firstMember.firstProperty. In my code I can call my function like this:

```<code>findInsertPoint(forElement: 7 in Array: testArray.map({$0.0}))
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have an array of tuples of Int, CustomType, OtherCustomType. The array is sorted by the Int part of the tuples.

To add new elements at the correct position I wrote a binary search function to get the insertion point index.

The function returns a new tuple of Int, Bool, where Bool tells if the element is already present, and Int is either the index of the first occurrence of the new element, or the index of the first element which is larger than the new element.

The function is written genericly, and takes an array of a comparable type and a new element of the same type as arguments, so, obviously, I cannot simply pass my array of tuples.

A simple solution would be to re-organize my data so, instead of storing three values as tuples in one array, I could use three separate arrays, each of only one of the three values. I would then pass only the first array to the binary search function and then perform the desired action on all three arrays at the found index.

But is there a way to keep my data organized as tuples and pass only one element of each tuple to the function, like we are able to ignore parts of a tuple in comparisons like if tuple == (_ ,23, _) ?

Here is some sample code:

func findInsertPoint <T: Comparable> (forElement: T, inArray: [T]) -> (Int, Bool) {
    var low = 0
    var high = inArray.count

    if forElement > inArray[high-1] {
        return (high, false)
    }
    while low < high {
        let mid = (low+high)/2
        if inArray[mid] >= forElement {
            high = mid
        } else {
            low = mid+1
        }
    }
    return(low,(inArray[low] == forElement))
}

An array of Ints works perfectly fine:

// index         0 1 2 3 4 5  6  7  8  9  10 11 12 13 14 15
var testArray = [1,2,5,7,8,11,12,12,12,15,19,22,22,26,52,56]

findInsertPoint(forElement: x, inArray: testArray)

// x = 17 returns (10,false)
// x = 19 returns (10,true)

But my actual array looks something like this:

var testArray = [(4,"Bee",2.5),(5,"dog",1.0),(8,"dog",43.13)]

How do I pass an array of only the first part of each tuple, but without the expensive creation of an actual new array each function call?

A possibility would be to call the function:

findInsertPoint(forElement: 7 in Array: testArray.0)

which would be perfect, but I know this doesn't work.

Is there a Swift way to temporarily ignore members of a tuple or a struct for a function call that only accepts arrays of a single type?

If not, I know my two possibilities are:

stick to my taylored binary search, not the generic one from the code above.

divide the tuple into 3 separate arrays.

Body:
This is the solution I found:

If you have an array of types which are collection types on their own, and you want to look only at a certain property of each member of the outer array, use the .map method of swift's collection type:

var testArray = [(4,"Bee",2.5),(5,"dog",1.0),(8,"dog",43.13)]
var onlyFirstProperty = testArray.map({$0.0}) // [4,5,8]

This way you'll get a new array which consists only of the first elements of each tuple. $0.0 is shorthand syntax for firstMember.firstProperty. In my code I can call my function like this:

findInsertPoint(forElement: 7 in Array: testArray.map({$0.0}))


问:
How to use configuration file for Azure web app
I want to deploy an app on Azure Web App engine and I encountered a problem:
My app is depended on outside configuration file, which contains DB access keys and some other configuration keys I don't want to save hard-coded.

Anyway, I thought to use configuration service like Spring with Git or some other similar services to handle the configuration but all of the solutions I found were heavy.

I bet I'm not the first one who struggle with this. So What is the common way to use out configuration file with Web-App?

答:
you can have any of the below ways to maintain application settings or connection strings.

directly use from web.config.
All the app settings and connection strings would be hard coded in configuration file and publish the same to Azure Web App. this is not recommended to store secrets/connection strings

you can use Application Settings provided by App Service from the portal

these settings will override keys provided in Web.Config file. you can have connection strings and secrets updated here instead of web.config to avoid direct exposure to end developer.

you can have all you secrets and connection strings in Azure Key Vault and refer to them from web application as URI(REST)
for this, you need to register your web app with Azure AD.
this is highly recommended way for production web sites.

UPDATE
Incorporated this answer into my blog post here


问:
What kind of LDA performs 'fitcdiscr' function?
I know that the new fitcdiscr MATLAB® function can perform several discriminant analysis, such as LDA or QDA. However, the mentions about 'regularization' and 'bayesian' inside the MATLAB® help confuse me.

What kind of discriminant analysis is performed if fitcdiscr uses the default parameters? Do it use Bayesian Linear Discriminant Analysis (BLDA), Fisher's LDA (FLDA), or some kind of Regularized LDA (rLDA)?

答:
What kind of discriminant analysis is performed if fitcdiscr uses the default parameters?

According to Matlab's documentation, it seems they are using "Regularized linear discriminant analysis" as default 'DiscrimType'.

Take a look to the image below:

fitcdiscr default discriminant type


问:
Unable to open connection: Host does not exist
I have been to access Jupyter Notebook on remote server (on a gpu). I followed this guide but getting this error "Unable to open connection: Host does not exist" after running the following command:

```<code> C::\WINDOWS\system32> plink ssh -N -L localhost:8888:localhost:8889 remote_user@remote_host
</code>```

OS: Windows

Using plink to create ssh tunnel.

Any idea what's going wrong ?

答:
And again solved this problem by using this command:

```<code>plink -ssh -L 8888:localhost:8888 ml_test #ml_test is my putty session name, you can provide your username@remote-host
</code>```

As mentioned in this question.

Body:
I have been to access Jupyter Notebook on remote server (on a gpu). I followed this guide but getting this error "Unable to open connection: Host does not exist" after running the following command:

 C::\WINDOWS\system32> plink ssh -N -L localhost:8888:localhost:8889 remote_user@remote_host

OS: Windows

Using plink to create ssh tunnel.

Any idea what's going wrong ?

Body:
And again solved this problem by using this command:

plink -ssh -L 8888:localhost:8888 ml_test #ml_test is my putty session name, you can provide your username@remote-host

As mentioned in this question.


问:
Does the tf.contrib.learn.Estimator class use all the data?
I have a training operation :

```<code>def train(self, batch_size, steps):
    x, y = self.generate(batch_size*steps)
    print('Training...')
    self.classifier.fit(x=x, y=y, batch_size=batch_size, steps=steps)
</code>```

And the classifier is defined here :

```<code>self.classifier = learn.Estimator(model_fn=self.model, model_dir=self.dir)
</code>```

My question is this - if x and y are bigger in size than batch_size, do they all get used when moving along the steps? For example, if the batch_size is 128, but both x and y are 128,000 items, do all items get trained on by the time steps reaches 1000 steps?

I'm asking this because the generate function takes a really long time, and I want to know if most of that time is wasted if it is actually the case that only the first batch_size of examples from it are used.

Note: I know the x and y arguments are deprecated and I should use input_fn instead, so the question applies to both ways, for example if the training operation was this:

```<code>def train(self, batch_size, steps):
    self.classifier.fit(input_fn=lambda: self.generate(batch_size*steps), steps=steps)
</code>```

In other words, the input_fn function, or the function that generates x,y tensors, should it be called with a demand for batch_size*steps data examples or just batch_size, because only that would be processed anyway?

答:
If your batch_size is 128 and if you have 128000 items then all items get trained when steps reached 1000 steps. The estimator only pulls what you have described in batch_size for every training step.

I have written a piece of code, which reads inputs (each sample is just 1), and every training step sums up the ones it has seen till that time, which tells you how many data samples it has read till that time.

```<code>from tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib

tf.logging.set_verbosity(tf.logging.INFO)

def model_fn(features, labels, mode):

   _sum = tf.Variable(0, dtype=tf.int32)

   if mode == learn.ModeKeys.TRAIN:
       # Update global_step
       global_step=tf.contrib.framework.get_global_step()
       global_step_op = tf.assign(global_step, global_step+1)

       # Sum of all the elements in a batch
       update_sum_op = tf.assign_add(_sum, tf.reduce_sum(features))
       update_op = tf.group(global_step_op, update_sum_op)
       loss = _sum

   predictions = {'out': tf.identity(_sum, 'sum')}

   return model_fn_lib.ModelFnOps(mode=mode, predictions=predictions, loss=loss, train_op=update_op)

X = np.ones((1000, 1), dtype=np.int32)
y = np.ones((1000, 1), dtype=np.int32)

sess = tf.InteractiveSession()

feature_classifier = learn.SKCompat(learn.Estimator(model_fn=model_fn))
tensors_to_log = {'out':'sum'}
logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=1)
feature_classifier.fit(x=X, y=y, batch_size=123, steps=7, monitors=[logging_hook])
</code>```

Here the total data samples is 1000 and the batch_size=123 and steps=7.

The output at each step is:

```<code>INFO:tensorflow:out = 123
INFO:tensorflow:out = 246 (0.004 sec)
INFO:tensorflow:out = 369 (0.003 sec)
INFO:tensorflow:out = 492 (0.003 sec)
INFO:tensorflow:out = 615 (0.003 sec)
INFO:tensorflow:out = 738 (0.003 sec)
INFO:tensorflow:out = 861 (0.003 sec)
</code>```

Body:
I have a training operation :

def train(self, batch_size, steps):
    x, y = self.generate(batch_size*steps)
    print('Training...')
    self.classifier.fit(x=x, y=y, batch_size=batch_size, steps=steps)

And the classifier is defined here :

self.classifier = learn.Estimator(model_fn=self.model, model_dir=self.dir)

My question is this - if x and y are bigger in size than batch_size, do they all get used when moving along the steps? For example, if the batch_size is 128, but both x and y are 128,000 items, do all items get trained on by the time steps reaches 1000 steps?

I'm asking this because the generate function takes a really long time, and I want to know if most of that time is wasted if it is actually the case that only the first batch_size of examples from it are used.

Note: I know the x and y arguments are deprecated and I should use input_fn instead, so the question applies to both ways, for example if the training operation was this:

def train(self, batch_size, steps):
    self.classifier.fit(input_fn=lambda: self.generate(batch_size*steps), steps=steps)

In other words, the input_fn function, or the function that generates x,y tensors, should it be called with a demand for batch_size*steps data examples or just batch_size, because only that would be processed anyway?

Body:
If your batch_size is 128 and if you have 128000 items then all items get trained when steps reached 1000 steps. The estimator only pulls what you have described in batch_size for every training step.

I have written a piece of code, which reads inputs (each sample is just 1), and every training step sums up the ones it has seen till that time, which tells you how many data samples it has read till that time.

from tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib

tf.logging.set_verbosity(tf.logging.INFO)

def model_fn(features, labels, mode):

   _sum = tf.Variable(0, dtype=tf.int32)

   if mode == learn.ModeKeys.TRAIN:
       # Update global_step
       global_step=tf.contrib.framework.get_global_step()
       global_step_op = tf.assign(global_step, global_step+1)

       # Sum of all the elements in a batch
       update_sum_op = tf.assign_add(_sum, tf.reduce_sum(features))
       update_op = tf.group(global_step_op, update_sum_op)
       loss = _sum

   predictions = {'out': tf.identity(_sum, 'sum')}

   return model_fn_lib.ModelFnOps(mode=mode, predictions=predictions, loss=loss, train_op=update_op)

X = np.ones((1000, 1), dtype=np.int32)
y = np.ones((1000, 1), dtype=np.int32)

sess = tf.InteractiveSession()

feature_classifier = learn.SKCompat(learn.Estimator(model_fn=model_fn))
tensors_to_log = {'out':'sum'}
logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=1)
feature_classifier.fit(x=X, y=y, batch_size=123, steps=7, monitors=[logging_hook])

Here the total data samples is 1000 and the batch_size=123 and steps=7.

The output at each step is:

INFO:tensorflow:out = 123
INFO:tensorflow:out = 246 (0.004 sec)
INFO:tensorflow:out = 369 (0.003 sec)
INFO:tensorflow:out = 492 (0.003 sec)
INFO:tensorflow:out = 615 (0.003 sec)
INFO:tensorflow:out = 738 (0.003 sec)
INFO:tensorflow:out = 861 (0.003 sec)


问:
Cannot understand the Output of this Code
```<code>void abc(int n) {
    if (n <= 10) {
        abc(++n);
        printf("%d\n", n);
    }
}

void main() {
    int m = 5;
    abc(m);
}
</code>```

The output shows:

```<code>11
10
9
8
7
6
</code>```

I cannot understand the output. Please explain. I am a novice code lover.

答:
First off in these lines of code, what is the output?

```<code>printf("7\n");
printf("6\n");
</code>```

If you guess 7 before 6 you are correct. If you call two functions that prints something, the one called first will output first. This is very important

Lets first rewrite your function so that each line doesn't do separate things. I'm thinking of the mutating ++n:

```<code>void abc(int n) {
    if (n <= 10) {
        n = n + 1;
        abc(n);
        printf("%d\n", n);
    }
}
</code>```

So if you pass 9 to this it will first change n to 10, then call abc(10) and get the output of that before it prints 10. The call to abc(10) increases its n to 11 and calls abc(11) first, which doesn't do anything, then does its printf "11\n" and returns to the call where n is 10 and do its printf "10\n" before it returns to the initial call.

The output is:

```<code>11
10
</code>```

If you do abc(5) it works the same. abc(6) needs to output first. And in abc(6) abc(7) needs to output first all the way to 11 thet doesn' have output and then it goes back, prints 11, 10, .... n + 1.

You can do it the other way around!

Lets say you start at the base case abc(11) and see the code doesn't do anything.

Then you look at abc(10). You see it will first increase n to 11, then call abc(11) which we previously saw does nothing and then it prints n, thus 11. Thus abc(10) prints "11\n".

If you look at abc(9) you see that n increases to 10, then it calls abc(10). You already know that that it prints "11\n", then it does its printf adding `"10\n" to the output, thus:

```<code>11
10
</code>```

Now if you do this with one number lower you eventually get to abc(5).. It increases n to 6, then calls abc(6) which you know outputs "11\n10\n9\n8\n7\n" and then it does the next line that prints "6\n" making the output of abc(5) "11\n10\n9\n8\n7\n6\n"

Body:
void abc(int n) {
    if (n <= 10) {
        abc(++n);
        printf("%d\n", n);
    }
}

void main() {
    int m = 5;
    abc(m);
}

The output shows:

11
10
9
8
7
6

I cannot understand the output. Please explain. I am a novice code lover.

Body:
First off in these lines of code, what is the output?

printf("7\n");
printf("6\n");

If you guess 7 before 6 you are correct. If you call two functions that prints something, the one called first will output first. This is very important

Lets first rewrite your function so that each line doesn't do separate things. I'm thinking of the mutating ++n:

void abc(int n) {
    if (n <= 10) {
        n = n + 1;
        abc(n);
        printf("%d\n", n);
    }
}

So if you pass 9 to this it will first change n to 10, then call abc(10) and get the output of that before it prints 10. The call to abc(10) increases its n to 11 and calls abc(11) first, which doesn't do anything, then does its printf "11\n" and returns to the call where n is 10 and do its printf "10\n" before it returns to the initial call.

The output is:

11
10

If you do abc(5) it works the same. abc(6) needs to output first. And in abc(6) abc(7) needs to output first all the way to 11 thet doesn' have output and then it goes back, prints 11, 10, .... n + 1.

You can do it the other way around!

Lets say you start at the base case abc(11) and see the code doesn't do anything.

Then you look at abc(10). You see it will first increase n to 11, then call abc(11) which we previously saw does nothing and then it prints n, thus 11. Thus abc(10) prints "11\n".

If you look at abc(9) you see that n increases to 10, then it calls abc(10). You already know that that it prints "11\n", then it does its printf adding `"10\n" to the output, thus:

11
10

Now if you do this with one number lower you eventually get to abc(5).. It increases n to 6, then calls abc(6) which you know outputs "11\n10\n9\n8\n7\n" and then it does the next line that prints "6\n" making the output of abc(5) "11\n10\n9\n8\n7\n6\n"


问:
Can I add Diplo Audit Log Viewer to a defferent section
I'm using Diplo Audit Log Viewer in my umbraco project, when I download the package I get the log only in the developer section, where and how can I change the package so the audit log viewer will be display in a different section (not the developer) Does someone had this problem and solved it ?</p>

答:
You should be able to register it to a different section by editing the ~/config/Trees.config file - find the entry corresponding to the logviewer, and change the application attribute to the section you want it to appear in.

This should do the trick, although I haven't tried it myself as yet.


问:
Make script run once per pageload
How do I make the following, run only once per pageload...

```<code>$(window).scroll(function(){
    if($(document).scrollTop()>=$(document).height()/5)
        $("#spopup").show("slow");else $("#spopup").hide("slow");
});
</code>```

Here is what I use to close the pop up in case that makes a difference...

```<code>function closeSPopup(){
    $('#spopup').hide('slow');
}
</code>```

http://codepen.io/john84/pen/vgWVRp

I was reading up on the .one() function but am unsure as where to put it

http://api.jquery.com/one/

答:
there is many ways to do this. i think setting a flag is going to work :</p>

```<code>var isopen = false;
$(window).on('scroll', function(){
    if($(document).scrollTop() >= $(document).height()/5 && isopen == false) {
        $("#spopup").show("slow");
        isopen = true;
        $(window).off('scroll');
    }
});
</code>```

Title: Make script run once per pageload

Body:
How do I make the following, run only once per pageload...

$(window).scroll(function(){
    if($(document).scrollTop()>=$(document).height()/5)
        $("#spopup").show("slow");else $("#spopup").hide("slow");
});

Here is what I use to close the pop up in case that makes a difference...

function closeSPopup(){
    $('#spopup').hide('slow');
}

http://codepen.io/john84/pen/vgWVRp

I was reading up on the .one() function but am unsure as where to put it

http://api.jquery.com/one/

Body:
there is many ways to do this. i think setting a flag is going to work :

var isopen = false;
$(window).on('scroll', function(){
    if($(document).scrollTop() >= $(document).height()/5 && isopen == false) {
        $("#spopup").show("slow");
        isopen = true;
        $(window).off('scroll');
    }
});


问:
Not able to delete selected polygon in ui-gmap-google-map
I am able to draw multiple polygon by using Google Draw manager. Now I am not able to select specific polygon from multiple polygon and delete and edit it. Also not able to get new array after edit or delete.

My demo.js code is as follows :

```<code>$scope.map = {
        center: { latitude: 19.997454, longitude: 73.789803 },
        zoom: 10,
        //mapTypeId: google.maps.MapTypeId.ROADMAP,
        //radius: 15000,
        stroke: {
            color: '#08B21F',
            weight: 2,
            opacity: 1
        },
        fill: {
            color: '#08B21F',
            opacity: 0.5
        },
        geodesic: true, // optional: defaults to false
        draggable: false, // optional: defaults to false
        clickable: false, // optional: defaults to true
        editable: false, // optional: defaults to false
        visible: true, // optional: defaults to true
        control: {},
        refresh: "refreshMap",
        options: { scrollwheel: true },
        Polygon: {
            visible: true,
            editable: true,
            draggable: true,
            geodesic: true,
            stroke: {
                weight: 3,
                color: 'red'
            }
        },
   source: {
            id: 'source',
            coords: {
                'latitude': 19.9989551,
                'longitude': 73.75095599999997
            },
            options: {
                draggable: false,
                icon: 'assets/img/person.png'
            }
        },
        isDrawingModeEnabled: true
    };

   $scope.drawingManagerOptions = {
        drawingControl: true,
        drawingControlOptions: {
            position: google.maps.ControlPosition.TOP_CENTER,
            drawingModes: [
              //google.maps.drawing.OverlayType.CIRCLE,
              google.maps.drawing.OverlayType.POLYGON,
            ]
        },
        circleOptions: {
            fillColor: '#BCDCF9',
            fillOpacity:0.5,
            strokeWeight: 2,
            clickable: false,
            editable: true,
            zIndex: 1
        },
        polygonOptions: {
            fillColor: '#BCDCF9',
            strokeColor: '#57ACF9',
            fillOpacity: 0.5,
            strokeWeight: 2,
            clickable: false,
            editable: true,
            zIndex: 1
        }
    };
    var coords = [];
    var polygon;
    $scope.eventHandler = {
        polygoncomplete: function (drawingManager, eventName, scope, args) {
            polygon = args[0];
            var path = polygon.getPath();
            for (var i = 0 ; i < path.length ; i++) {
                coords.push({
                    latitude: path.getAt(i).lat(),
                    longitude: path.getAt(i).lng()
                });
            }
    },
    };

    $scope.removeShape = function () {
        google.maps.event.clearListeners(polygon, 'click');
        google.maps.event.clearListeners(polygon, 'drag_handler_name');
        polygon.setMap(null);
    }
</code>```

And My HTML code is as follows :

```<code><ui-gmap-google-map center="map.center" zoom="map.zoom" options="map.options" control="map.control">
                <ui-gmap-marker coords="map.source.coords"
                                options="map.source.options"
                                idkey="map.source.id">
                </ui-gmap-marker>

                <ui-gmap-drawing-manager options="drawingManagerOptions" control="drawingManagerControl" events="eventHandler"></ui-gmap-drawing-manager>
            </ui-gmap-google-map>
</code>```

You can find polygon image for reference:

Now I want to select one of polygon from following image and want to delete or update it.

Some help will be really appreciable.

答:
By the ui-google-map plugin's drawing manager doc, you could get the google.maps.drawing.DrawingManager object by the control attributes (putting there an object)

```<code><ui-gmap-drawing-manager control="drawingManagerControl" options="drawingManagerOptions"></ui-gmap-drawing-manager>
</code>```

and

```<code>$scope.drawingManagerControl = {};
//Now get the drawingManager object
var drawingManager = $scope.drawingManagerControl.getDrawingManager();
</code>```

Having this object is the main work.
Now you can look on everything you need. For your case you need the overlaycomplete events, it will listen for every time you have drawn a shape (=> polygon , circle, polyline)

```<code>google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
  var newShape = e.overlay;
});
</code>```

newShape is the new shape drawn, polygon in your case, so  you can use it like a Polygon object and can use all you need in this reference.

Now I want to select one of polygon from following image and want to
  delete or update it.

For it, we'll distinct the polygon selected, by assigning it in a global variable: eg var selectedShape;

And now, Add a click event listener for this drawn polygon and update it as the selectedShape, and now to delete or update, you can use the selectedShape variable.

```<code>var selectedShape;
... ...
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
    var newShape = e.overlay;
    google.maps.event.addListener(newShape, 'click', function() {
        selectedShape = newShape;
    });
});
</code>```

Finally you can delete the selected shape by setting his map to null selectedShape.setMap(null); and update the shape by setting it editable to true shape.setEditable(true);

And finally to make these click event possible you need to add clickable options to true for all shape.
PS: Use the IsReady Service to have map ready before working on it

Working plunker: https://embed.plnkr.co/qfjkT2lOu2vkATisGbw7/

Update:

But how to get all co-ordinates of multiple polygon after edit or
  draw.

you already have this in your script, in polygonecomplete ($scope.eventHandler). Now you can add it in overlaycomplete events listener, and for everytime you updated the shape (see code bellow)

But challenge is how to identify which polygon is edited on the
  map and how to update that specific polygon from my array

You can push in an array for each shape created and could manage it:

```<code> ...
 var allShapes = []; //the array contains all shape, to save in end
 ....
//get path coords: I use your code there
function getShapeCoords(shape) {
  var path = shape.getPath();
  var coords = [];
  for (var i = 0; i < path.length; i++) {
    coords.push({
      latitude: path.getAt(i).lat(),
      longitude: path.getAt(i).lng()
    });
  }
  return coords;
}
....
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
    var newShape = e.overlay;
    google.maps.event.addListener(newShape, 'click', function() {
        selectedShape = newShape;
    });
    ...
    // get coordinate of the polygon
    var shapeCoords = getShapeCoords(newShape);
    // pushing this shape to allShapes array
    allShapes.push(newShape);
});
</code>```

in the delete function you can delete id by the index of the selectedShape

```<code>//delete selected shape
function deleteSelectedShape() {
  if (!selectedShape) {
    alert("There are no shape selected");
    return;
  }
  var index = allShapes.indexOf(selectedShape);
  allShapes.splice(index, 1);
  selectedShape.setMap(null);
</code>```

}

Now you have the allShapes array, and in the end you can loop it then get for each coordinates and save in your db.

I updated the plunker and added some debug log do show you.

Body:
I am able to draw multiple polygon by using Google Draw manager. Now I am not able to select specific polygon from multiple polygon and delete and edit it. Also not able to get new array after edit or delete.

My demo.js code is as follows :

$scope.map = {
        center: { latitude: 19.997454, longitude: 73.789803 },
        zoom: 10,
        //mapTypeId: google.maps.MapTypeId.ROADMAP,
        //radius: 15000,
        stroke: {
            color: '#08B21F',
            weight: 2,
            opacity: 1
        },
        fill: {
            color: '#08B21F',
            opacity: 0.5
        },
        geodesic: true, // optional: defaults to false
        draggable: false, // optional: defaults to false
        clickable: false, // optional: defaults to true
        editable: false, // optional: defaults to false
        visible: true, // optional: defaults to true
        control: {},
        refresh: "refreshMap",
        options: { scrollwheel: true },
        Polygon: {
            visible: true,
            editable: true,
            draggable: true,
            geodesic: true,
            stroke: {
                weight: 3,
                color: 'red'
            }
        },
   source: {
            id: 'source',
            coords: {
                'latitude': 19.9989551,
                'longitude': 73.75095599999997
            },
            options: {
                draggable: false,
                icon: 'assets/img/person.png'
            }
        },
        isDrawingModeEnabled: true
    };

   $scope.drawingManagerOptions = {
        drawingControl: true,
        drawingControlOptions: {
            position: google.maps.ControlPosition.TOP_CENTER,
            drawingModes: [
              //google.maps.drawing.OverlayType.CIRCLE,
              google.maps.drawing.OverlayType.POLYGON,
            ]
        },
        circleOptions: {
            fillColor: '#BCDCF9',
            fillOpacity:0.5,
            strokeWeight: 2,
            clickable: false,
            editable: true,
            zIndex: 1
        },
        polygonOptions: {
            fillColor: '#BCDCF9',
            strokeColor: '#57ACF9',
            fillOpacity: 0.5,
            strokeWeight: 2,
            clickable: false,
            editable: true,
            zIndex: 1
        }
    };
    var coords = [];
    var polygon;
    $scope.eventHandler = {
        polygoncomplete: function (drawingManager, eventName, scope, args) {
            polygon = args[0];
            var path = polygon.getPath();
            for (var i = 0 ; i < path.length ; i++) {
                coords.push({
                    latitude: path.getAt(i).lat(),
                    longitude: path.getAt(i).lng()
                });
            }
    },
    };

    $scope.removeShape = function () {
        google.maps.event.clearListeners(polygon, 'click');
        google.maps.event.clearListeners(polygon, 'drag_handler_name');
        polygon.setMap(null);
    }

And My HTML code is as follows :

<ui-gmap-google-map center="map.center" zoom="map.zoom" options="map.options" control="map.control">
                <ui-gmap-marker coords="map.source.coords"
                                options="map.source.options"
                                idkey="map.source.id">
                </ui-gmap-marker>

                <ui-gmap-drawing-manager options="drawingManagerOptions" control="drawingManagerControl" events="eventHandler"></ui-gmap-drawing-manager>
            </ui-gmap-google-map>

You can find polygon image for reference:

Now I want to select one of polygon from following image and want to delete or update it.

Some help will be really appreciable.

Body:
By the ui-google-map plugin's drawing manager doc, you could get the google.maps.drawing.DrawingManager object by the control attributes (putting there an object)

<ui-gmap-drawing-manager control="drawingManagerControl" options="drawingManagerOptions"></ui-gmap-drawing-manager>

and

$scope.drawingManagerControl = {};
//Now get the drawingManager object
var drawingManager = $scope.drawingManagerControl.getDrawingManager();

Having this object is the main work.
Now you can look on everything you need. For your case you need the overlaycomplete events, it will listen for every time you have drawn a shape (=> polygon , circle, polyline)

google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
  var newShape = e.overlay;
});

newShape is the new shape drawn, polygon in your case, so  you can use it like a Polygon object and can use all you need in this reference.

Now I want to select one of polygon from following image and want to
  delete or update it.

For it, we'll distinct the polygon selected, by assigning it in a global variable: eg var selectedShape;

And now, Add a click event listener for this drawn polygon and update it as the selectedShape, and now to delete or update, you can use the selectedShape variable.

var selectedShape;
... ...
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
    var newShape = e.overlay;
    google.maps.event.addListener(newShape, 'click', function() {
        selectedShape = newShape;
    });
});

Finally you can delete the selected shape by setting his map to null selectedShape.setMap(null); and update the shape by setting it editable to true shape.setEditable(true);

And finally to make these click event possible you need to add clickable options to true for all shape.
PS: Use the IsReady Service to have map ready before working on it

Working plunker: https://embed.plnkr.co/qfjkT2lOu2vkATisGbw7/

Update:

But how to get all co-ordinates of multiple polygon after edit or
  draw.

you already have this in your script, in polygonecomplete ($scope.eventHandler). Now you can add it in overlaycomplete events listener, and for everytime you updated the shape (see code bellow)

But challenge is how to identify which polygon is edited on the
  map and how to update that specific polygon from my array

You can push in an array for each shape created and could manage it:

 ...
 var allShapes = []; //the array contains all shape, to save in end
 ....
//get path coords: I use your code there
function getShapeCoords(shape) {
  var path = shape.getPath();
  var coords = [];
  for (var i = 0; i < path.length; i++) {
    coords.push({
      latitude: path.getAt(i).lat(),
      longitude: path.getAt(i).lng()
    });
  }
  return coords;
}
....
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
    var newShape = e.overlay;
    google.maps.event.addListener(newShape, 'click', function() {
        selectedShape = newShape;
    });
    ...
    // get coordinate of the polygon
    var shapeCoords = getShapeCoords(newShape);
    // pushing this shape to allShapes array
    allShapes.push(newShape);
});

in the delete function you can delete id by the index of the selectedShape

//delete selected shape
function deleteSelectedShape() {
  if (!selectedShape) {
    alert("There are no shape selected");
    return;
  }
  var index = allShapes.indexOf(selectedShape);
  allShapes.splice(index, 1);
  selectedShape.setMap(null);

}

Now you have the allShapes array, and in the end you can loop it then get for each coordinates and save in your db.

I updated the plunker and added some debug log do show you.


问:
what the name for the item in the green circle
what's the element name in the green circle? Whta's the event corresponding to click this element?

答:
If you want to disable the selectall button you can also do like this:

```<code>  //Disable select all button
  datagrid.CommandBindings.Add(new CommandBinding(DataGrid.SelectAllCommand, delegate { }, (s, a) => { if (a.OriginalSource is Button) ((Button)a.OriginalSource).IsEnabled = false; }));
</code>```

as a workaround.
This can also be used to wire other things up.

The "problem" with re-templating is that you have to take all the themes into account... tedious :)

ContentLicense: CC BY-SA 2.5

Body:
If you want to disable the selectall button you can also do like this:

  //Disable select all button
  datagrid.CommandBindings.Add(new CommandBinding(DataGrid.SelectAllCommand, delegate { }, (s, a) => { if (a.OriginalSource is Button) ((Button)a.OriginalSource).IsEnabled = false; }));

as a workaround.
This can also be used to wire other things up.

The "problem" with re-templating is that you have to take all the themes into account... tedious :)


问:
Java regex with String.match() for integers
I Am trying to get certain numbers from my OCR text detector.
So far I have not been able to successfully extract the numbers
with a certain format.
The number looks similar to this 5225 6128 3265 4455
generally, the format could be like this XXXX XXXX XXXX XXXX

I need a string match regex to get such a number.
NOTE: There are other numbers from picture source I need to avoid capturing
Here is the method

```<code>List<? extends Text> textComponents = text.getComponents();
for (Text currentText : textComponents) {
    float left = translateX(currentText.getBoundingBox().left);
    float bottom = translateY(currentText.getBoundingBox().bottom);
    canvas.drawText(currentText.getValue(),left,bottom,sTectPaint);

    // get certain type of text
    if(currentText !=null && currentText.getValue() != null) {
        if (currentText.getValue().matches("^[0-9]+(0-9]+[0-9]+[0-9]") || currentText.getValue().contains("0123456789")) {
            Log.e("number", currentText.getValue());
            myNum = "";
            myNum = currentText.getValue();
        }
    }
}
</code>```

答:
Something like that? This will match 4 groups of exactly 4 digits each, separated by a whitespace:

```<code>public static void main (String[] args) throws java.lang.Exception
{
    System.out.println(matches("1234 5678 1234 9872"));
    System.out.println(matches("1234 5678 1234 9872 3265"));
    System.out.println(matches("134 5678 1234 9872"));
    System.out.println(matches("1234 5678 14 982"));
    System.out.println(matches("1234"));
    System.out.println(matches("1234 5678 12345 9872"));
}

private static boolean matches(String text) {
    return text.matches("^\\d{4} \\d{4} \\d{4} \\d{4}");
}
</code>```

Output:

```<code>true
false
false
false
false
false
</code>```

Depending on what your input exactly looks like you might need to alter the regular expression a bit, though.

Body:
I Am trying to get certain numbers from my OCR text detector.
So far I have not been able to successfully extract the numbers
with a certain format.
The number looks similar to this 5225 6128 3265 4455
generally, the format could be like this XXXX XXXX XXXX XXXX

I need a string match regex to get such a number.
NOTE: There are other numbers from picture source I need to avoid capturing
Here is the method

List<? extends Text> textComponents = text.getComponents();
for (Text currentText : textComponents) {
    float left = translateX(currentText.getBoundingBox().left);
    float bottom = translateY(currentText.getBoundingBox().bottom);
    canvas.drawText(currentText.getValue(),left,bottom,sTectPaint);

    // get certain type of text
    if(currentText !=null && currentText.getValue() != null) {
        if (currentText.getValue().matches("^[0-9]+(0-9]+[0-9]+[0-9]") || currentText.getValue().contains("0123456789")) {
            Log.e("number", currentText.getValue());
            myNum = "";
            myNum = currentText.getValue();
        }
    }
}

Body:
Something like that? This will match 4 groups of exactly 4 digits each, separated by a whitespace:

public static void main (String[] args) throws java.lang.Exception
{
    System.out.println(matches("1234 5678 1234 9872"));
    System.out.println(matches("1234 5678 1234 9872 3265"));
    System.out.println(matches("134 5678 1234 9872"));
    System.out.println(matches("1234 5678 14 982"));
    System.out.println(matches("1234"));
    System.out.println(matches("1234 5678 12345 9872"));
}

private static boolean matches(String text) {
    return text.matches("^\\d{4} \\d{4} \\d{4} \\d{4}");
}

Output:

true
false
false
false
false
false

Depending on what your input exactly looks like you might need to alter the regular expression a bit, though.


问:
How do I check which version of NumPy I'm using?
How can I check which version of NumPy I'm using?</p>

答:
```<code>import numpy
print numpy.__version__
</code>```

Body:
import numpy
print numpy.__version__


问:
Query data and return as a JSON string
I need some help in extracting data from a tabel into Json.
I need to query the data and return all the records for the current year that meets the WHERE statement and at the same time group the results by MONTH.

What I have as the query is:

```<code>$query_Promoter = "
SELECT COUNT(RecordID) AS Score4, FeedBackDate
FROM ".$FeedBack."
WHERE FeedBackDate >= DATE_SUB(NOW(),INTERVAL 1 YEAR)
    AND A = 4
    OR B = 4
    OR C = 4
    OR D = 4
    OR E = 4
    OR F = 4
    OR G = 4
    OR H = 4
    OR L = 4
    OR M = 4
    OR N = 4
GROUP BY MONTH(FeedBackDate)";
$Promoter =$conn->query($query_Promoter);
$totalRows_Promoter  = mysqli_num_rows($Promoter);
</code>```

I then loop through the result like:

```<code>if($totalRows_Promoter > 0) {
    $rows_Promoter  = array();
    $rows_Promoter ['name'] = 'Promoters';
    while($row_Promoter  = mysqli_fetch_array($Promoter )) {
        $rows_Promoter['Month'][] = date("M", strtotime($row_Promoter['FeedBackDate']));
        $rows_Promoter['data'][] = $row_Promoter['Score4'];
    }
}

$result = array();

if($totalRows_Promoter > 0) {
    array_push($result,$rows_Promoter);
}

print json_encode($result, JSON_NUMERIC_CHECK);

// The resulting JSON is:

[{"name":"Promoters","Month":["Jan","Jan","Jan","Jan"],"data":[3,10,17,1]}]
</code>```

I am trying to get the result as :

```<code>[{"name":"Promoters","Month":["Jan","Feb","May","Jun"],"data":[3,10,17,1]}]
</code>```

Can anyone see what I am doing wrong or am I approaching this the wrong way.

Many thanks in advance for your time.

答:
You can do most of the work in the SQL statement. By using the GROUP_CONCAT function and the DATE_FORMAT function, you will end up with one row that can easily be turned into you array for JSON easily. Here's the SQL Statement:

```<code>SELECT
    'Promoters' as `name`,
    GROUP_CONCAT(DATE_FORMAT(`FeedBackDate`,'%b')) as `Month`,
    GROUP_CONCAT(COUNT(`RecordID`)) AS `data`
FROM $FeedBack
WHERE `FeedBackDate` >= DATE_SUB(NOW(),INTERVAL 1 YEAR)
    AND (A = 4
        OR B = 4
        OR C = 4
        OR D = 4
        OR E = 4
        OR F = 4
        OR G = 4
        OR H = 4
        OR L = 4
        OR M = 4
        OR N = 4)
ORDER BY DATE_FORMAT(`FeedBackDate`,'%b')
</code>```

To create the array from the row, you'll need to split up the two columns with the GROUP_CONCAT since they'll be comma separated strings.

```<code>if($totalRows_Promoter > 0) {
    $rows_Promoter  = array();
    $rows_Promoter['name'] = 'Promoters';
    //  Should only have one row in results
    $row_Promoter  = mysqli_fetch_array($Promoter );
    $rows_Promoter['Month'] = explode(',',$row_Promoter['Month']);
    $rows_Promoter['data'] = explode(',',$row_Promoter['data']);
}

$result = json_encode($result, JSON_NUMERIC_CHECK);

echo $result;
</code>```

Title: Query data and return as a JSON string

Body:
I need some help in extracting data from a tabel into Json.
I need to query the data and return all the records for the current year that meets the WHERE statement and at the same time group the results by MONTH.

What I have as the query is:

$query_Promoter = "
SELECT COUNT(RecordID) AS Score4, FeedBackDate
FROM ".$FeedBack."
WHERE FeedBackDate >= DATE_SUB(NOW(),INTERVAL 1 YEAR)
    AND A = 4
    OR B = 4
    OR C = 4
    OR D = 4
    OR E = 4
    OR F = 4
    OR G = 4
    OR H = 4
    OR L = 4
    OR M = 4
    OR N = 4
GROUP BY MONTH(FeedBackDate)";
$Promoter =$conn->query($query_Promoter);
$totalRows_Promoter  = mysqli_num_rows($Promoter);

I then loop through the result like:

if($totalRows_Promoter > 0) {
    $rows_Promoter  = array();
    $rows_Promoter ['name'] = 'Promoters';
    while($row_Promoter  = mysqli_fetch_array($Promoter )) {
        $rows_Promoter['Month'][] = date("M", strtotime($row_Promoter['FeedBackDate']));
        $rows_Promoter['data'][] = $row_Promoter['Score4'];
    }
}

$result = array();

if($totalRows_Promoter > 0) {
    array_push($result,$rows_Promoter);
}

print json_encode($result, JSON_NUMERIC_CHECK);

// The resulting JSON is:

[{"name":"Promoters","Month":["Jan","Jan","Jan","Jan"],"data":[3,10,17,1]}]

I am trying to get the result as :

[{"name":"Promoters","Month":["Jan","Feb","May","Jun"],"data":[3,10,17,1]}]

Can anyone see what I am doing wrong or am I approaching this the wrong way.

Many thanks in advance for your time.

Body:
You can do most of the work in the SQL statement. By using the GROUP_CONCAT function and the DATE_FORMAT function, you will end up with one row that can easily be turned into you array for JSON easily. Here's the SQL Statement:

SELECT
    'Promoters' as `name`,
    GROUP_CONCAT(DATE_FORMAT(`FeedBackDate`,'%b')) as `Month`,
    GROUP_CONCAT(COUNT(`RecordID`)) AS `data`
FROM $FeedBack
WHERE `FeedBackDate` >= DATE_SUB(NOW(),INTERVAL 1 YEAR)
    AND (A = 4
        OR B = 4
        OR C = 4
        OR D = 4
        OR E = 4
        OR F = 4
        OR G = 4
        OR H = 4
        OR L = 4
        OR M = 4
        OR N = 4)
ORDER BY DATE_FORMAT(`FeedBackDate`,'%b')

To create the array from the row, you'll need to split up the two columns with the GROUP_CONCAT since they'll be comma separated strings.

if($totalRows_Promoter > 0) {
    $rows_Promoter  = array();
    $rows_Promoter['name'] = 'Promoters';
    //  Should only have one row in results
    $row_Promoter  = mysqli_fetch_array($Promoter );
    $rows_Promoter['Month'] = explode(',',$row_Promoter['Month']);
    $rows_Promoter['data'] = explode(',',$row_Promoter['data']);
}

$result = json_encode($result, JSON_NUMERIC_CHECK);

echo $result;


问:
PHP search funtion makes my website collapse
Im just creating a webpage with search feature and in every search i have a database query that brings back suggestions. But when i fire this onkeyup fucntion too many times (I mean 10-20 time) because its getting fired again and again while tryping, after too many firing website colapses and gives me an error page, standart google chore error page (not the php error pages that explain whats wrong) after 1 minute, everything goes normal. Do you have any idea?

Thank You.

Here is my JS Code

```<code>    var timer;
    $('#search').keyup(function(e){
            timer = setTimeout(function(){
        var searchname = $('#search').val();
        $.ajax({
            url:"php/fetchsuggest.php",
            type:'POST',
            data:{searchname:searchname},
            success: function(data){
                $('#fetch').show();
                $('#fetch').html(data);

                //select fetch as val
                $('.fetched').click(function(){
                    var innerval=$(this).text();
                    $('#search').val(innerval);
                    $('#fetch').hide();
                    $('#search').focus();
                });
            }
        });
        },300);
    });
</code>```

答:
@apokryfos is exactly right in his comment.

Your onkeyup event handler somehow starts a MySQL query: possibly via an ajax-style request from your user's browser to your php page.  Then, before the MyQL query has a chance to finish and return its result set to the browser, the next event handler starts another query.

Once a MySQL query has started (in the usual php implementations), it runs to completion. That's true even if the user closes the browser-to-php connection while the query is in progress.  If your user is capable of kicking off many queries quickly -- by typing fast -- those queries will pile up in the MySQL server until it runs out of resources.

There's a possible vicious cycle here. The user thinks "maybe my request didn't go through" and clicks again, starting yet another request.

The jQueryUI Autocomplete widget has a delay parameter to control how often a request gets sent. http://api.jqueryui.com/autocomplete/#option-delay In my experience a setting of one to two seconds yields a high-quality user experience. You may find it helpful to use such a widget; somebody else has already debugged the complexities of javascript timeouts used for delays.

Body:
Im just creating a webpage with search feature and in every search i have a database query that brings back suggestions. But when i fire this onkeyup fucntion too many times (I mean 10-20 time) because its getting fired again and again while tryping, after too many firing website colapses and gives me an error page, standart google chore error page (not the php error pages that explain whats wrong) after 1 minute, everything goes normal. Do you have any idea?

Thank You.

Here is my JS Code

    var timer;
    $('#search').keyup(function(e){
            timer = setTimeout(function(){
        var searchname = $('#search').val();
        $.ajax({
            url:"php/fetchsuggest.php",
            type:'POST',
            data:{searchname:searchname},
            success: function(data){
                $('#fetch').show();
                $('#fetch').html(data);

                //select fetch as val
                $('.fetched').click(function(){
                    var innerval=$(this).text();
                    $('#search').val(innerval);
                    $('#fetch').hide();
                    $('#search').focus();
                });
            }
        });
        },300);
    });


问:
Cannot access https on codeigniter
The following is my base_url of config.php in my project.

```<code>$config['base_url'] = 'https://www.mywebsite.com/';
</code>```

But my website always go to http://www.mywebsite.com unless the user implicitly write https in browser url.

What is the problem?

Why codeigniter goes to url that define in config.php ?

答:
HTTPS :- Full name is (hyper text transfer protocol secure). It’s a extended or you can say secure version of the HTTP(hyper text transfer protocol). If you have https enabled on your server you will get a lock icon in address bar of browser.
For encryption of data it’s used SSL(secure sockets layer) certificates to install on your server. Most uses of https to securely transmit data with ssl.
So most of sites need ssl or https url. we can easily manage redirection to https url in codeigniter using hooks. it’s a one more good feature of CI. We need to create some lines of code to get ssl url or redirect to https url in codeigniter. Default codeigniter not have this type of functionality so we need to force redirect to ssl url. below we will see how to use ssl redirect with codeigniter.

1.Config changes :- application/config/config.php and enable or set hooks to true.

```<code>$config['enable_hooks'] = TRUE;
</code>```

2.create a new file named hooks.php in application/config/hooks.php and add below code in hooks.php.

```<code>$hook['post_controller_constructor'][] = array(

                                'function' => 'redirect_ssl',

                                'filename' => 'ssl.php',

                                'filepath' => 'hooks'

                                );
</code>```

3.Now create a new directory with named hooks under application directory and then create new file named ssl.php in application/hooks/ssl.php
and add below code to ssl.php.

```<code>function redirect_ssl() {

    $CI =& get_instance();

    $class = $CI->router->fetch_class();

    $exclude =  array('client');  // add more controller name to exclude ssl.

    if(!in_array($class,$exclude)) {

      // redirecting to ssl.

      $CI->config->config['base_url'] = str_replace('http://', 'https://', $CI->config->config['base_url']);

      if ($_SERVER['SERVER_PORT'] != 443) redirect($CI->uri->uri_string());

    }

    else {

      // redirecting with no ssl.

      $CI->config->config['base_url'] = str_replace('https://', 'http://', $CI->config->config['base_url']);

      if ($_SERVER['SERVER_PORT'] == 443) redirect($CI->uri->uri_string());

    }

}
</code>```

Now check your site you will get https in url. redirect to https url in codeigniter using hooks is a good method rather than htaccess.

Title: Cannot access https on codeigniter

Body:
The following is my base_url of config.php in my project.

$config['base_url'] = 'https://www.mywebsite.com/';

But my website always go to http://www.mywebsite.com unless the user implicitly write https in browser url.

What is the problem?

Why codeigniter goes to url that define in config.php ?

Body:
HTTPS :- Full name is (hyper text transfer protocol secure). It’s a extended or you can say secure version of the HTTP(hyper text transfer protocol). If you have https enabled on your server you will get a lock icon in address bar of browser.
For encryption of data it’s used SSL(secure sockets layer) certificates to install on your server. Most uses of https to securely transmit data with ssl.
So most of sites need ssl or https url. we can easily manage redirection to https url in codeigniter using hooks. it’s a one more good feature of CI. We need to create some lines of code to get ssl url or redirect to https url in codeigniter. Default codeigniter not have this type of functionality so we need to force redirect to ssl url. below we will see how to use ssl redirect with codeigniter.

1.Config changes :- application/config/config.php and enable or set hooks to true.

$config['enable_hooks'] = TRUE;

2.create a new file named hooks.php in application/config/hooks.php and add below code in hooks.php.

$hook['post_controller_constructor'][] = array(

                                'function' => 'redirect_ssl',

                                'filename' => 'ssl.php',

                                'filepath' => 'hooks'

                                );

3.Now create a new directory with named hooks under application directory and then create new file named ssl.php in application/hooks/ssl.php
and add below code to ssl.php.

function redirect_ssl() {

    $CI =& get_instance();

    $class = $CI->router->fetch_class();

    $exclude =  array('client');  // add more controller name to exclude ssl.

    if(!in_array($class,$exclude)) {

      // redirecting to ssl.

      $CI->config->config['base_url'] = str_replace('http://', 'https://', $CI->config->config['base_url']);

      if ($_SERVER['SERVER_PORT'] != 443) redirect($CI->uri->uri_string());

    }

    else {

      // redirecting with no ssl.

      $CI->config->config['base_url'] = str_replace('https://', 'http://', $CI->config->config['base_url']);

      if ($_SERVER['SERVER_PORT'] == 443) redirect($CI->uri->uri_string());

    }

}

Now check your site you will get https in url. redirect to https url in codeigniter using hooks is a good method rather than htaccess.


问:
How to save the data into File in java?
I have one problem, that is I have one string of data and I want to save it into a separate file every time. Please give me a suggestion.

Thanks,
vara kumar.pjd

答:
Use a timestamp in the filename so you can be sure it is unique. Below example uses a timestamp in milliseconds which should be enough in most cases.

If you expect you can have multiple files within 1 millisecond then you could do something with a GUID/UUID. Note that GUID/UUID could result in duplicates too, however this chance is extremely rare.

```<code>import java.io.*;
class FileWrite
{
   public static void main(String args[])
  {
      try{
    // Create file
    FileWriter fstream = new FileWriter(System.currentTimeMillis() + "out.txt");
        BufferedWriter out = new BufferedWriter(fstream);
    out.write("Hello Java");
    //Close the output stream
    out.close();
    }catch (Exception e){//Catch exception if any
      System.err.println("Error: " + e.getMessage());
    }
  }
}
</code>```

Title: How to save the data into File in java?

Body:
Use a timestamp in the filename so you can be sure it is unique. Below example uses a timestamp in milliseconds which should be enough in most cases.

If you expect you can have multiple files within 1 millisecond then you could do something with a GUID/UUID. Note that GUID/UUID could result in duplicates too, however this chance is extremely rare.

import java.io.*;
class FileWrite
{
   public static void main(String args[])
  {
      try{
    // Create file
    FileWriter fstream = new FileWriter(System.currentTimeMillis() + "out.txt");
        BufferedWriter out = new BufferedWriter(fstream);
    out.write("Hello Java");
    //Close the output stream
    out.close();
    }catch (Exception e){//Catch exception if any
      System.err.println("Error: " + e.getMessage());
    }
  }
}


问:
Pure functions: state content vs. state reference
In this pen, I am having a hard time understanding why when using the push function on a newly created const (line 24) it matters whether one uses the spread operator or simply copies "state" over. How is it that replacing [...state] with state causes state to be overwritten with the content of newState?

Am I correct in assuming that it is the reference to state which is overwritten if state is directly passed to newState? I.e. in the case of const newState = state

答: Using the spread operator like this will take all the items from state and create a new array with these items. So state and newState will reference different arrays (which have the same elements, so if one of these elements is an object and you change one of it's properties, that change will be visible in the other array). Writing const newState = state will result in one array and two references to that array, since you're not creating a second array anywhere.